Why constructors cannot be declared as virtual functions, destructors can

Source: Internet
Author: User
Tags inheritance

turn from: http://blog.csdn.net/chen825919148/article/details/8020550

constructors cannot be declared as virtual functions, destructors can be declared as virtual functions, and sometimes they must be declared as virtual functions.
It is not recommended to call virtual functions inside constructors and destructors.

The reason that a constructor cannot be declared as a virtual function is:
1 when constructing an object, you must know the actual type of the object, while the virtual function behavior determines the actual type during run time. When an object is constructed, the object is not yet successfully constructed. The compiler cannot know the actual type of the object, whether it is the class itself, a derived class of that class, or a deeper derived class. Unable to determine ...

2 execution of virtual functions relies on virtual function tables. The virtual function table initializes the work in the constructor, that is, initialize the vptr, and let him point to the correct virtual function table. The virtual function table is not initialized and cannot be performed during the construction of the object.a virtual function means that dynamic binding is turned on, and the program chooses the method to invoke based on the dynamic type of the object. However, when the constructor is running, the dynamic type of the object is incomplete and there is no way to determine what type it is, so the constructor cannot be dynamically bound. (Dynamic binding is based on the dynamic type of an object rather than the name of the function, and before the constructor is invoked, the object does not exist at all, and how it is dynamically bound.) )
The compiler does not know when calling the constructor of a base class whether you are constructing an object of a base class or an object of a derived class.

the destructor is set to the function of a virtual function:
Explain:In the inheritance of a class, if there is a base class pointer to a derived class, the part of the derived class that derives from the derived classes cannot be refactored if the base class pointer is not defined as a virtual function.
Cases:
#include "stdafx.h"
#include "stdio.h"
Class A
{
Public
A ();
Virtual~a ();
};
A::a ()
{
}

A::~a ()
{
printf ("Delete class APn");
}
Class B:public A
{
Public
B ();
~b ();
};

B::b ()
{ }

B::~b ()
{
printf ("Delete class BPn");
}
int main (int argc, char* argv[])
{
A *b=new B;
Delete B;
return 0;
}

The output is: Delete class B
Delete class A

if the virtual of a is removed: it becomes delete Class A that means that the remainder of the derived class is not deleted, or the virtual function of the derived class is not invoked

therefore, in the inheritance system of the class, the destructor of the base class is not declared as a virtual function, which can easily cause memory leaks. So if you're designing a class that might be a base class, you have to declare it as a virtual function. Just like the CBase in Symbian. Note:
1. If we define a constructor, the compiler will no longer generate a default constructor for us.
2. The compiler-generated destructor is non-virtual, unless it is a subclass whose parent class has a virtual destructor, at which point the function virtual attribute comes from the parent class.
3. Classes with virtual functions can almost be determined to have a virtual destructor.
4. If a class cannot be a base class, do not affirm that destructors are virtual functions and that virtual functions are space-consuming.
5. The exception exit of the destructor will cause the destructor to be incomplete, resulting in a memory leak. It is best to provide a management class that provides a way to refactor in the management class, and the caller then determines the next action based on the result of this method.
6. Do not call virtual functions in constructors. When a base class is constructed, the virtual function is non-virtual and does not go to the derived class, both as a static binding. Obviously: when we construct an object of a subclass, we first call the constructor of the base class, constructs the base class part of the subclass, the subclass is not yet constructed, it is not initialized, if you call a virtual function in the construction of the base class, it is dangerous to call a object that has not been initialized, so C + + is the virtual function implementation of a subclass that is not allowed to be invoked when the parent object part is constructed. But not that you can not write the program, you write so, the compiler will not report an error. It's just that if you write this, the compiler will not give you a call to the implementation of the subclass, but the implementation of the base class.
7.
do not call virtual functions in a destructor either. The destructor of the subclass is called first in the destructor, and the subclass part of the object is destructor. It is then very dangerous to invoke the destructor of the base class to destructor the base class part, and to invoke the virtual function inside the destructor of the base class, which causes it to invoke functions inside the subclass object that has been destructor.

8. Remember that when you write a copy function of a derived class, you call the copy function of the base class to copy the part of the base class, and you can't forget it.


turn from: http://blog.sina.com.cn/s/blog_7c773cc50100y9hz.html

1. First paragraph code

#include <iostream>
using namespace Std;
Class clxbase{
Public
Clxbase () {};
~clxbase () {cout << "Output from the destructor of Class clxbase!" << Endl;

void DoSomething () {cout << ' do something in class clxbase! ' << Endl;
};

Class Clxderived:public clxbase{
Public
Clxderived () {};
~clxderived () {cout << "Output from the destructor of Class clxderived!" << Endl;

void DoSomething () {cout << ' do something in class clxderived! ' << Endl;
};
int main () {
clxderived *p = new clxderived;
P->dosomething ();
Delete p;
return 0;
}

Run Result:

Do something in class clxderived!

Output from the destructor of class clxderived!

Output from the destructor of class clxbase!

The destructor of the base class in this code is not a virtual function, the member of the inheriting class is manipulated with the pointer of the inheriting class in the main function, and the process of releasing the pointer P is to release the resource of the inheriting class and then release the base class resource.

2. Second paragraph code

#include <iostream>
using namespace Std;
Class clxbase{
Public
Clxbase () {};
~clxbase () {cout << "Output from the destructor of Class clxbase!" << Endl;

void DoSomething () {cout << ' do something in class clxbase! ' << Endl;
};

Class Clxderived:public clxbase{
Public
Clxderived () {};
~clxderived () {cout << "Output from the destructor of Class clxderived!" << Endl;

void DoSomething () {cout << "do Something in class clxderived!" << Endl;}
};
int main () {
Clxbase *p = new clxderived;
P->dosomething ();
Delete p;
return 0;
}

Output results:

Do something in class clxbase!
Output from the destructor of class clxbase!

The destructor of the base class in this code is also not a virtual function, the difference is to manipulate the members of the inheriting class with a pointer to the base class in the main function, and the process of releasing the pointer p is to simply free the resource of the base class without invoking the destructor of the inheriting class. Call DoSomething () function is also a function that is defined by the base class.

In general, such a deletion can only delete the base class object, but not the subclass object, resulting in the deletion of half image, resulting in memory leaks.

In public inheritance, the operations of a base class on a derived class and its objects can affect only those members inherited from the base class. If you want to manipulate a non-inherited member with a base class, define this function of the base class as a virtual function.

The destructor should naturally be the same: if it wants to deconstruct the redefinition or new members and objects in subclasses, it should be declared virtual as well.

3. Third paragraph code:

#include <iostream>
using namespace Std;
Class clxbase{
Public
Clxbase () {};
Virtual ~clxbase () {cout << "Output from the destructor of Class clxbase!" << Endl;
virtual void dosomething () {cout << ' do something in class clxbase! ' << Endl;
};

Class Clxderived:public clxbase{
Public
Clxderived () {};
~clxderived () {cout << "Output from the destructor of Class clxderived!" << Endl;
void DoSomething () {cout << ' do something in class clxderived! ' << Endl;
};

int main () {
Clxbase *p = new clxderived;
P->dosomething ();
Delete p;
return 0;
}

Run Result:

Do something in class clxderived!
Output from the destructor of class clxderived!
Output from the destructor of class clxbase!

The destructor of the base class in this code is defined as a virtual function, to manipulate the members of the inheriting class with a pointer to the base class in the main function, the process of releasing the pointer P is to simply release the resource of the inheriting class and then call the destructor of the base class. Call the DoSomething () function to perform a function that is also defined by the inheriting class.

If you do not need a base class to manipulate derived classes and objects, you cannot define a virtual function because it increases the memory overhead. When a class has a virtual function defined, the compiler adds a virtual function table to the class that holds the virtual function pointer, which increases the storage space of the class. So, The destructor is written as a virtual function only when a class is used as a base class.

turn from: http://www.51projob.com/a/bishimianshi/2012/0414/195.html

In fact, this question will eventually answer a question:

If base * pbase = new Derived, then how to avoid memory leaks if delete pbase. comparison 1: Ordinary member functions and virtual functions of the parent class are not virtual functions

To see what happens this time, the specific code and the results of the operation are as follows:

< /pre>
#include  <iostream>  using namespace std;   //Scenario 1: Normal member functions and destructors, not virtual functions   class base{  public:      base () {}  The destructor of the     //parent class, Not virtual function       ~base () {          cout<< " Base destructor "<<endl;      }      //General member       void dosomething () {          cout< < "do something in base" <<endl;      } }; //derived class   class derived : public base{  public:      derived () {}      ~derived () {          cout<< "Derived  destructor "<<endl;      }      void dosomeThing () {          cout<< "do something in  Derived "<<endl;      } };    int main () {       //this time, although the parent class pointer actually points to a subclass, there is no virtual function table, so the actual type cannot be invoked, so the output can only be what the parent pointer itself can see       base  *base = new Derived;      base->dosomething ()//output is a function of the parent class       delete base;//is called the destructor       system of the parent class (

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.