Does a base class's constructor and destructor get called with the derived ones?
I have a class called MyBase which has a constructor and destructor:
class MyBase
{
public:
MyBase(void);
~MyBase(void);
};
and I have a class called Banana, that extends MyBase like so:
class Banana:public MyBase
{
public:
Banana(void);
~Banana(void);
};
Does the implementation of the new constructor and destructor in Banana override the MyBase ones, or do they still exist, and get called say before or after the Banana c开发者_如何转开发onstructor / destructor executes?
Thanks, and my apologies if my question seems silly.
A Base constructor will always be called before the derived constructor. The Base destructor will be called after Dervided destructor.
You can specify on derived constructor which Base constructor you want, if not the default one will be executed.
If you define other constructors but not default and don't specify on Derived constructor which one to execute it'll try default which doesn't exist and will crash compilation.
The above happens because once you declare one constructor no default constructors are generated.
Constructors cannot be overriden. You can't declare a base class constructor in a derived class. A class constructor has to call a constructor in base class (if one is not explicitly stated, the default constructor is called) prior to anything else.
To be able to clean up the derived class correctly, you should declare the base class destructor as virtual
:
virtual ~MyBase() { ... }
It should say
class Banana : public MyBase
{
public:
Banana(void);
~Banana(void);
};
The constructor of the derived class gets called after the constructor of the base class. The destructors get called in reversed order.
The constructors are called top down in the inheritance tree. This is so that the derived constructor can count on the base object being fully initialized before it tries to use any properties of the base.
Destructors are called in reverse order of the constructors, for the same reason - the derived classes depend on the base, but the base doesn't depend on the derived.
If there is any possibility of destroying the object through a pointer to a base class, you must declare all of the destructors virtual
.
Constructors and destructors are special member functions. In general you will read everywhere that construction starts from the least derived type all the way in the hierarchy down to the most derived type. This is actually the order in which constructor execution completes, but not how construction is started.
Constructors initialization list execution order guarantees that while the most derived object's constructor will be the first constructor to start executing it will be the last constructor to complete
When you instantiate an object the most derived constructor that matches the construction call gets called first. The initialization list of the matched most derived constructor starts, and initialization lists have a fixed order: first the constructors of the base classes in order or appearance within the inheritance list get called. Then the member attribute constructors are called in the order in which they appear in the class declaration (not the order in which they appear in the initialization list). After the whole initialization list (at each level) completes, the constructor body block is executed, after which the constructor call completes.
All base destructors will be called in reverse order of construction after the most derived destructor has completed execution. Destruction happens in exact reverse order of construction.
Destructors are special in a different way: they cannot be overriden. When you call the most derived destructor of a class, it will complete the execution of the destructor body, after which all member attribute destructors will be called in reverse order of creation. After the most derived destructor has completed and so have done the member destructors of the most derived object, the destructor of its most direct bases start in reverse order of construction, the destructor bodies will execute, then the member attributes destructors and so on... At the end all constructed elements will be destroyed.
Destructors for polymorphic classes should be virtual
The destruction description above starts with the call to the most derived destructor. This can be achieved by calling delete
on a pointer to the most derived type, when an auto object goes out of scope or when the object is delete
d through a base class whose destructor is virtual.
If you forget to add the destructor keyword in the base class and you try to delete a derived object through a pointer to the base you will call the base destructor directly, and that implies that all sub objects below the pointer type in the hierarchy will not be properly destroyed. All inheritance hierarchies in which you will delete objects through pointers to a base type must have virtual destructors. As a general rule of thumb, if you already have any virtual method, the cost of making the destructor virtual is negligible and is a safe net. Many coding guides enforce that destructors in inheritance hierarchies must be virtual. Some go as far as requesting all destructors to be virtual, This has the intention of avoiding possible resource leaks at the cost of adding a vtable for all types and an vtable pointer for all objects.
You are missing the type of inheritance:
Change
class Banana:MyBase
To:
class Banana: public MyBase
As for
does the implementation of the new constructor and destructor in Banana override the MyBase ones, or do they still exist, and get called say before or after the Banana constructor / destructor executes?
The order of inherited executes from bottom to top, that means that MyBase will be called first, then Banana. If you had another subclass, it would be called last.
Take this example:
class RottenBanana : public Banana
The inheritance chain is now RottenBanana -> Banana -> MyBase
The constructors of this class will be called starting at MyBase, then Banana and then calling RottenBanana.
If you instantiate an EEGModeRGB object (which has tri-color led's attached) - then immediately delete it you'd see the colors Blue, Green, Yellow, and Red, for one second each - in that order.
class EEGMode {
public:
EEGMode() { setAllPixelsToColor(BLUE); delay(1000); }
virtual ~EEGMode() { setAllPixelsToColor(RED); delay(1000); }
};
class EEGModeRGB : public EEGMode {
public:
EEGModeRGB() { setAllPixelsToColor(GREEN); delay(1000); }
virtual ~EEGModeRGB() { setAllPixelsToColor(YELLOW); delay(1000); }
};
精彩评论