Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2011-06

Problem with virtual constructors

5 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jorge Aldo G. de F. Junior

I am having problems with virtual methods.

I have two classes, the second one is a descendent of the first :

1st:

	TTreeNode = Class(TObject)
	Public
		Constructor Create(Const aOwner : TTreeNode); Virtual;
2nd :
	TTreeNodeWithProperties = Class(TTreeNodeWithName)
	Public
		Constructor Create(Const aOwner : TTreeNodeWithProperties); Override;

TTreeNodeWithName is the ancestor of TTreeNodeWithProperties, and TTreeNode is the ancestor of TTreeNodeWithName.

TTreeNode -> TTreeNodeWithName -> TTreeNodeWithProperties

TTreeNodeWithName use the old constructor from the base class (IE.: It doesnt define a new constructor), so it works ok.

TTreeNodeWithProperties needs to hook the constructor/destructor to build some aditional encapsulated objects,
so i need to Override the virtual constructor.

As you can see i am using virtual constructors.

The problem is :

If i use Override it causes this output from the compiler :

{
Free Pascal Compiler version 2.4.4 [2011/04/22] for i386 Copyright (c) 1993-2010 by Florian Klaempfl
Target OS: Linux for i386
Compiling htmlnodes.pas
Compiling tree.pas
Compiling namevalue.pas
tree.pas(89,15) Error: There is no method in an ancestor class to be overridden: "constructor TTreeNodeWithProperties.Create(const TTreeNodeWithProperties);"
tree.pas(125,1) Fatal: There were 1 errors compiling module, stopping Fatal: Compilation aborted
}

If i use Reintroduce the compiler doesnt complain, but when the class is instantiated from a class factory, it builds the wrong class (the constructor called is of the base class not of the derived one).
IE.: The aditional objects i need in the derived class are not instantiated, giving a big access violation exception during runtime.

If i leave without override or reintrodce, the compiler complains :

{
Free Pascal Compiler version 2.4.4 [2011/04/22] for i386 Copyright (c) 1993-2010 by Florian Klaempfl
Target OS: Linux for i386
Compiling htmlnodes.pas
Compiling tree.pas
Compiling namevalue.pas
tree.pas(89,15) Warning: An inherited method is hidden by "constructor TTreeNodeWithProperties.Create(const TTreeNodeWithProperties);" htmlnodes.pas(34,15) Error: There is no method in an ancestor class to be overridden: "constructor
THTMLNode.Create(TTreeNodeWithProperties);"
htmlnodes.pas(80,1) Fatal: There were 1 errors compiling module, stopping Fatal: Compilation aborted
}

I think i am doing something wrong...
I'm left without options...
Pls Help.

Reply by email

cobines
to Jorge Aldo G. de F. Junior

2011/6/1 Jorge Aldo G. de F. Junior :

Show quoted text 15 lines
I am having problems with virtual methods. I have two classes, the second one is a descendent of the first : 1st:        TTreeNode = Class(TObject)        Public                Constructor Create(Const aOwner : TTreeNode); Virtual; 2nd :        TTreeNodeWithProperties = Class(TTreeNodeWithName)        Public                Constructor Create(Const aOwner : TTreeNodeWithProperties); Override;

TTreeNode is a different type than TTreeNodeWithProperties.

I think you should override the constructor with base type as param:

   Constructor Create(Const aOwner :  TTreeNode); Override;

At runtime check with:

if not (aOwner is TTreeNodeWithProperties) then
  raise exception....
inherited Create(aOwner);
...

If you define a different constructor with the derived type as param :

   Constructor Create(Const aOwner :  TTreeNodeWithProperties); Overload;

then if you're passing TTreeNode objects to TTreeNodeWithProperties constructor it will only call the base constructor.

cobines

Reply by email

leledumbo
to Jorge Aldo G. de F. Junior: I am having problems with virtual methods. I have two classes, the second one is a…

Yep, this situation would confuse the compiler as it's possible to assign descendant class instance to a class.
1st solution: rename one of the constructor, don't need to use virtual/override
2nd solution: try using constref instead of const (I hope constref has the same semantics as var for classes, where the assigned object must be exactly the instance of expected class, descendants not allowed)

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Problem-with-virtual-constructors-tp4445729p4445832.html Sent from the Free Pascal - General mailing list .

Reply by email

Jorge Aldo G. de F. Junior
to leledumbo

2011/6/1 leledumbo :

Yep, this situation would confuse the compiler as it's possible to assign descendant class instance to a class. 1st solution: rename one of the constructor, don't need to use virtual/override

Its a class factory, i cannot have multiple constructors, so i need virtual constructors in order to build classes from names.

2nd solution: try using constref instead of const (I hope constref has the same semantics as var for classes, where the assigned object must be exactly the instance of expected class, descendants not allowed)

I will try that.

Show quoted text 8 lines
-- View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Problem-with-virtual-constructors-tp4445729p4445832.html Sent from the Free Pascal - General mailing list . _______________________________________________ fpc-pascal maillist  -   http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Jorge Aldo G. de F. Junior
to Jorge Aldo G. de F. Junior

Cobines solution worked !

not tested constref.

2011/6/1 Jorge Aldo G. de F. Junior :

Show quoted text 24 lines
2011/6/1 leledumbo : > Yep, this situation would confuse the compiler as it's possible to assign > descendant class instance to a class. > 1st solution: rename one of the constructor, don't need to use > virtual/override Its a class factory, i cannot have multiple constructors, so i need virtual constructors in order to build classes from names. > 2nd solution: try using constref instead of const (I hope constref has the > same semantics as var for classes, where the assigned object must be exactly > the instance of expected class, descendants not allowed) I will try that. > > -- > View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Problem-with-virtual-constructors-tp4445729p4445832.html > Sent from the Free Pascal - General mailing list . > _______________________________________________ > fpc-pascal maillist  -   > http://lists.freepascal.org/mailman/listinfo/fpc-pascal >

Reply by email