tags:

views:

490

answers:

4

Should I call "inherited" in the constructor of a class derived from TObject or TPersistent?

constructor TMyObject.Create;
begin
 inherited Create;   // Delphi doc: Do not create instances of TPersistent. Use TPersistent as a base class when declaring objects that are not components, but that need to be saved to a stream or have their properties assigned to other objects.    
 VectorNames := TStringList.Create;
 Clear;
end;
+22  A: 

Yes. It does nothing, true, but it's harmless. I think there is value in being consistent about always calling the inherited constructor, without checking to see if there is, in fact, an implementation. Some will say that it's worth calling inherited Create because Embarcadero might add an implementation for TObject.Create in the future, but I doubt this is true; it would break existing code which does not call inherited Create. Still, I think it is a good idea to call it for the reason of consistency alone.

Craig Stuntz
Indeed, it's a good habit
The_Fox
"It does nothing"??!! It initiates the basic object storage! And may do required stuff defined in a base class you're inheriting. Not calling it may result in the worst kind of errors and bugs: those that you don't find out what is going on rightaway.
Stijn Sanders
IIRC, the basic storage is already allocated before your constructor (Create) is called.
mj2008
mj2008, you are right. Stijn, you are wrong. Read the source!
Craig Stuntz
Hi Stjin. I think in TObject it does nothing.
Altar
I think the most important reason is the one Gamecat stated - at some point you may want to reparent your class from TObject to something else and new class may contain non-trivial constructor.
gabr
That is a special case of "be consistent," but I agree, I like the way he put it.
Craig Stuntz
@Stijn, the constructor of TObject does nothing, allocating storage is done by NewInstance, initalizing by InitInstance. Both class methods of TObject.
Gamecat
But don't call inherited on methods that override abstract methods (or have stuff like Assert('Create must be overridden') in the base class!
Gerry
+9  A: 

I always does this.

If you are refactoring and move code to a common ancestor, calling the inherited Create has the follwoing advantages:

  1. If the common ancestor has a constructor, you can't forget to call it.
  2. If the common ancestor has a constructor with different parameters, the compiler warns you for this.
Gamecat
Although Craig is right offcourse, these are also my main reasons to call inherited Create, more so than being consistent.
Lieven
A: 

You can also override "procedure AfterConstruction". This procedure is always called, no matter what kind of constructor.

public
  procedure AfterConstruction; override;
end;

procedure TfrmListBase.AfterConstruction;
begin
  inherited;
  //your stuff, always initialized, no matter what kind of constructor!
end;

For example: if you want to create an object with a different constructor than the normal TObject.Create, such as TComponent.Create(AOwner) or a custom (overloaded) constructor, you can get problems because your override is not called and (in this case) your "VectorNames" variable will be nil.

André
If your overridden constructor isn't called, then it's a bug in your descendant class. That's a problem for the descendant-class developer to worry about, not you. And it IS possible to skip a call to AfterConstruction, for the same reason you can skip a call to the constructor: The descendant provides its own implementation and neglects to call the inherited method.
Rob Kennedy
Rob: If you make a factory class, which generates TObject descendants, you cannot use TObject.Create() because it is not virtual! And if you make a TComponent descendant in your factory: it has a different constructor (Create(AOwner)). That's why you should use AfterConstruction: it is always called, no matter what kind of constructor
André
+1  A: 

I call it, except when i need a very optimized constructor.

Marcelo Rocha