admin管理员组文章数量:1289350
Now, we know that C++ constructors can not be virtual. But today I discovered something weird: the Borland compiler (bcc64) seems positive about virtual constructors, and in fact their VCL library, too (Vcl.Controls.hpp
, RAD Studio 12.2):
class PASCALIMPLEMENTATION TGraphicControl : public TControl
{
typedef TControl inherited;
private:
Vcl::Graphics::TCanvas* FCanvas;
MESSAGE void __fastcall WMPaint(Winapi::Messages::TWMPaint &Message);
protected:
virtual void __fastcall Paint();
__property Vcl::Graphics::TCanvas* Canvas = {read=FCanvas};
public:
__fastcall virtual TGraphicControl(System::Classes::TComponent* AOwner);
__fastcall virtual ~TGraphicControl();
};
In consequence, if I declare a class like:
class MyControl : public TGraphicControl
{
public:
MyControl(TComponent *Owner);
void __fastcall Paint() override;
};
the compiler will issue these warnings:
MyControl.h(18): 'MyControl' overrides a member function but is not marked 'override'
Vcl.Controls.hpp(2642): overridden virtual function is here
Weird! Is this some Delphi language extension? And if so, what sort of virtual member function will the compiler generate from the virtual constructor? Or is it just an inconsistency in the compiler implementation?
Now, we know that C++ constructors can not be virtual. But today I discovered something weird: the Borland compiler (bcc64) seems positive about virtual constructors, and in fact their VCL library, too (Vcl.Controls.hpp
, RAD Studio 12.2):
class PASCALIMPLEMENTATION TGraphicControl : public TControl
{
typedef TControl inherited;
private:
Vcl::Graphics::TCanvas* FCanvas;
MESSAGE void __fastcall WMPaint(Winapi::Messages::TWMPaint &Message);
protected:
virtual void __fastcall Paint();
__property Vcl::Graphics::TCanvas* Canvas = {read=FCanvas};
public:
__fastcall virtual TGraphicControl(System::Classes::TComponent* AOwner);
__fastcall virtual ~TGraphicControl();
};
In consequence, if I declare a class like:
class MyControl : public TGraphicControl
{
public:
MyControl(TComponent *Owner);
void __fastcall Paint() override;
};
the compiler will issue these warnings:
MyControl.h(18): 'MyControl' overrides a member function but is not marked 'override'
Vcl.Controls.hpp(2642): overridden virtual function is here
Weird! Is this some Delphi language extension? And if so, what sort of virtual member function will the compiler generate from the virtual constructor? Or is it just an inconsistency in the compiler implementation?
Share Improve this question edited Feb 21 at 10:07 AmigoJack 6,1742 gold badges19 silver badges34 bronze badges asked Feb 21 at 9:15 HendrikHendrik 6334 silver badges15 bronze badges 4- 3 The VCL was originally written in Delphi (which was object-oriented pascal, with some proprietary extensions). Early versions of Borland C++ used the compiled VCL directly, and needed some Borland-specific language extensions to interface to the VCL. Over time, the VCL was rewritten in C++ but (to maintain backward compatibility of code using the VCL) used those same language extensions. – Peter Commented Feb 21 at 9:52
- Look up class references in Delphi, or in Borland C++ Builder offline help. – Igor G Commented Feb 21 at 10:00
- 2 @Peter, the VCL is still written in Delphi Pascal. – Uli Gerhardt Commented Feb 21 at 20:25
- 2 @Peter the VCL (and RTL and FMX, too) is still written in Delphi. It was NEVER rewritten in C++, but there are various C++ classes and C++ compiler extensions mixed in to provide compatibility between C++ and Delphi, same as it always was. – Remy Lebeau Commented Feb 21 at 20:34
2 Answers
Reset to default 4Is this some Delphi language extension?
Yes.
The following text is an excerpt from Borland C++ Wiki (uses Delphi syntax):
A constructor can be called using a variable of a class-reference type. This allows construction of objects whose type isn't known at compile time. For example:
type TControlClass = class of TControl; function CreateControl(ControlClass: TControlClass; const ControlName: string; X, Y, W, H: Integer): TControl; begin Result := ControlClass.Create(MainForm); with Result do begin Parent := MainForm; Name := ControlName; SetBounds(X, Y, W, H); Visible := True; end; end;
The
CreateControl
function requires a class-reference parameter to tell it what kind of control to create. It uses this parameter to call the constructor of the class. Because class-type identifiers denote class-reference values, a call to CreateControl can specify the identifier of the class to create an instance of. For example:CreateControl(TEdit, 'Edit1', 10, 10, 100, 20);
Constructors called using class references are usually virtual. The constructor implementation activated by the call depends on the runtime type of the class reference.
In C++, such metaclass can be obtained with another Borland extension keyword: __classid
:
Application->CreateForm(__classid(TForm1), &Form1);
Here, CreateForm
method gets the metaclass as its first argument, and then can use that metaclass to call virtual constructor of Form1
or whichever actual visual control you want to construct.
Is this some Delphi language extension?
Yes, it is a C++ language extension for compatibility with Delphi.
In standard C++, classes are normally constructed from base-first to derived-last, which is why derived-class methods are not accessible to base-class constructors (the derived-class instance doesn't exist yet).
In Delphi, on the other hand, classes are constructed in the opposite order, from derived-first to base-last, thus derived-class methods are accessible to base-class constructors (the derived-class instance already exists), especially via polymorphic dispatch.
That is why virtual constructors can exist in Delphi classes, but not in standard C++ classes.
However, the C++ extension in question allows C++ classes which are marked with __declspec(delphiclass)
(ie, they are derived from Delphi's TObject
pascal class, as all VCL components are) to have virtual constructors, as they follow Delphi's creation model rather than C++'s creation model.
Most notably, per the __declspec(delphiclass)
documentation:
The
delphiclass
argument is used to declare Delphi-style classes. Such classes are created with the following compatibility:
- ...
- Delphi-compatible constructor/destructor behavior
- ...
...
Other remarks:
- Unlike regular C++ classes, the constructors and destructors of Delphi-style base classes can invoke virtual methods and run the "most derived" implementations. Thus, it is possible that a method of a class is executed before any constructor.
本文标签: oopWhat are Borland C virtual constructorsStack Overflow
版权声明:本文标题:oop - What are Borland C++ virtual constructors? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741395386a2376347.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论