Can constructor and destructor be declared as virtual functions?

Source: Internet
Author: User
Document directory
  • The constructor cannot be declared as a virtual function. The Destructor can be declared as a virtual function, and sometimes it must be declared as a virtual function.
The constructor cannot be declared as a virtual function. The Destructor can be declared as a virtual function, and sometimes it must be declared as a virtual function.

It is not recommended to call virtual functions in constructor and destructor.

The reason the constructor cannot be declared as a virtual function is:

Explanation 1: the so-called virtual function is to execute only one program under multi-state conditions. In terms of inheritance, it is always necessary to construct a parent class object before it can be a subclass object. If the constructor is set to a virtual function, You have to display the call constructor when constructing the constructor of the parent class. Another reason is to prevent errors. Imagine if you accidentally overwrite a function that is the same as the parent class constructor In the subclass, then the constructor of your parent class will be overwritten, that is, the parent class cannot be constructed. an error occurs.

Explanation 2: The main significance of a virtual function is that it is inherited by a derived class to generate polymorphism. In the constructor of a derived class, the compiler adds the code for constructing the base class. If the base class constructor uses parameters, the derived class must provide parameters for the base class in the initialization list of its constructor, that's why.

A virtual function means to enable dynamic binding. The program selects the method to be called 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 the type of the object. Therefore, the constructor cannot be dynamically bound. (Dynamic binding is based on the object's dynamic type rather than the function name. before calling the constructor, this object does not exist at all. How can it be dynamically bound ?)

The compiler does not know whether to construct a base class object or a derived class object when calling the base class constructor.

The function of setting the Destructor as a virtual function:

Explanation: In class inheritance, if a base class Pointer Points to a derived class, when the base class pointer is deleted, if it is not necessarily a virtual function, the derived part of the derived class cannot be analyzed.

Example:

# Include "stdafx. H"

# Include "stdio. H"

Class

{

Public:

A ();

Virtual ~ A ();

};

A: ()

{

}

A ::~ A ()

{

Printf ("delete class AP/N ");

}

Class B: public

{

Public:

B ();

~ B ();

};

B: B ()

{}

B ::~ B ()

{

Printf ("delete class BP/N ");

}

Int main (INT argc, char * argv [])

{

A * B = new B;

Delete B;

Return 0;

}

Output result: delete Class B

Delete Class

If the virtual of A is removed: it becomes Delete Class.

Therefore, in the class inheritance system, the destructor of the base class are not declared as virtual functions, which may cause memory leakage. Therefore, if you design a base class, you must declare it as a virtual function. Just like cbase in Symbian. Note:

1. if we define a constructor, the compiler will no longer generate default constructor for us.

2. The Destructor generated by the compiler is non-Virtual. Unless it is a subclass, its parent class has a virtual destructor. At this time, the virtual feature of the function comes from the parent class.

3. For classes with virtual functions, you can almost certainly have a virtual destructor.

4. If a class cannot be a base class, do not declare that the Destructor is a virtual function, which consumes space.

5. Abnormal exit of the Destructor may lead to incomplete structure and Memory leakage. It is best to provide a management class, provide a method in the management class to analyze the structure, the caller then decides the next operation based on the result of this method.

6. Do not call virtual functions in constructors. When constructing a base class, the virtual function is non-virtual and does not go to the derived class. It is both a static binding. Obviously, when we construct a subclass object, we first call the base class constructor to construct the base class part of the subclass. The subclass has not yet been constructed and has not been initialized, if you call a virtual function in the construction of the base class, it is very dangerous to call a non-initialized object if you can, therefore, in C ++, you cannot call the virtual function implementation of the subclass when constructing the parent class object. But it doesn't mean that you can't write programs that way, and the compiler won't report an error if you write the program that way. If you write this statement, the compiler will not call the implementation of the subclass, but will still call the implementation of the base class.

7. Do not call virtual functions in destructor. During the analysis, the sub-class destructor will be called first to parse the sub-class part of the object, and then the anti-constructor part of the base class will be called, if you call a virtual function in the destructor of the base class, it is very dangerous to call the function in the subclass object that has been destructed.

8. Remember to call the copy function of the base class to copy the part of the base class when writing the copy function of the derived class.

If a class is used as a base class, its fictitious function must be virtual, that is, the virtual keyword is used (the parameter is zero, it is a pure virtual function ).
Otherwise, there will be Memory leakage (very important), because when you use a base class pointer to delete an object of A derived class, you need to call the destructor of the derived class. However
The Destructor available for its subclass or sub-subclass can be a virtual function or a virtual function. (If the virtual keyword is not added, the derivation is not called.
Class destructor, and the preceding clxbase * Ptest = new clxderived; the statement is that the new clxderived object is not destroyed, resulting in Memory leakage)
2. virtual functions in a class. If a function in a class is declared as a virtual function, its subclass does not need to be declared as a virtual function (when the subclass has a subclass ),
It can also be declared as a virtual function. The result is the same. The truth of the virtual destructor is the same. Of course, it is not necessary to write all the class destructor.
Virtual function. Because when there is a virtual function in the class, the compiler will add a virtual function table to the class to store the virtual function pointer.
Will increase the storage space of the class. Therefore, only when a class is used as the base class can the Destructor be written as a virtual function.

Example:

# Include "iostream. H"

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 (){};
Virtual ~ Clxderived () {cout <"output from the destructor of class clxderived! "<Endl ;};

// Remove the virtual
Virtual void dosomething () {cout <"do something in class clxderived! "<Endl ;};

// Remove the virtual
};

Class clxthrived: Public clxderived
{
Public:
Clxthrived (){};
Virtual ~ Clxthrived () {cout <"output from the destructor of class clxthrived! "<Endl ;};

// Remove the virtual
Virtual void dosomething () {cout <"do something in class clxthrived! "<Endl ;}

// Remove the virtual
};
Void main ()
{
Clxbase * ptest1 = new clxbase;
Ptest1-> dosomething ();
Delete ptest1; // 1

Clxbase * ptest2 = new clxderived;
Ptest2-> dosomething ();
Delete ptest2; // 2 when the base class pointer is used to delete an object of A derived class

Clxderived * ptest3 = new clxderived;
Ptest3-> dosomething ();
Delete ptest3; // 3

Clxbase * ptest4 = new clxthrived;
Ptest4-> dosomething ();
Delete ptest4; // 4 when the base class pointer is used to delete an object of A derived class

Clxderived * ptest5 = new clxthrived;
Ptest5-> dosomething ();
Delete ptest5; // 5 when the base class pointer is used to delete an object of A derived class

Clxthrived * ptest6 = new clxthrived;
Ptest6-> dosomething ();
Delete ptest6; // 6
}

It is not recommended to call virtual functions in constructor and destructor.

The reason the constructor cannot be declared as a virtual function is:

Explanation 1: the so-called virtual function is to execute only one program under multi-state conditions. In terms of inheritance, it is always necessary to construct a parent class object before it can be a subclass object. If the constructor is set to a virtual function, You have to display the call constructor when constructing the constructor of the parent class. Another reason is to prevent errors. Imagine if you accidentally overwrite a function that is the same as the parent class constructor In the subclass, then the constructor of your parent class will be overwritten, that is, the parent class cannot be constructed. an error occurs.

Explanation 2: The main significance of a virtual function is that it is inherited by a derived class to generate polymorphism. In the constructor of a derived class, the compiler adds the code for constructing the base class. If the base class constructor uses parameters, the derived class must provide parameters for the base class in the initialization list of its constructor, that's why.

A virtual function means to enable dynamic binding. The program selects the method to be called 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 the type of the object. Therefore, the constructor cannot be dynamically bound. (Dynamic binding is based on the object's dynamic type rather than the function name. before calling the constructor, this object does not exist at all. How can it be dynamically bound ?)

The compiler does not know whether to construct a base class object or a derived class object when calling the base class constructor.

The function of setting the Destructor as a virtual function:

Explanation: In class inheritance, if a base class Pointer Points to a derived class, when the base class pointer is deleted, if it is not necessarily a virtual function, the derived part of the derived class cannot be analyzed.

Example:

# Include "stdafx. H"

# Include "stdio. H"

Class

{

Public:

A ();

Virtual ~ A ();

};

A: ()

{

}

A ::~ A ()

{

Printf ("delete class AP/N ");

}

Class B: public

{

Public:

B ();

~ B ();

};

B: B ()

{}

B ::~ B ()

{

Printf ("delete class BP/N ");

}

Int main (INT argc, char * argv [])

{

A * B = new B;

Delete B;

Return 0;

}

Output result: delete Class B

Delete Class

If the virtual of A is removed: it becomes Delete Class.

Therefore, in the class inheritance system, the destructor of the base class are not declared as virtual functions, which may cause memory leakage. Therefore, if you design a base class, you must declare it as a virtual function. Just like cbase in Symbian. Note:

1. if we define a constructor, the compiler will no longer generate default constructor for us.

2. The Destructor generated by the compiler is non-Virtual. Unless it is a subclass, its parent class has a virtual destructor. At this time, the virtual feature of the function comes from the parent class.

3. For classes with virtual functions, you can almost certainly have a virtual destructor.

4. If a class cannot be a base class, do not declare that the Destructor is a virtual function, which consumes space.

5. Abnormal exit of the Destructor may lead to incomplete structure and Memory leakage. It is best to provide a management class, provide a method in the management class to analyze the structure, the caller then decides the next operation based on the result of this method.

6. Do not call virtual functions in constructors. When constructing a base class, the virtual function is non-virtual and does not go to the derived class. It is both a static binding. Obviously, when we construct a subclass object, we first call the base class constructor to construct the base class part of the subclass. The subclass has not yet been constructed and has not been initialized, if you call a virtual function in the construction of the base class, it is very dangerous to call a non-initialized object if you can, therefore, in C ++, you cannot call the virtual function implementation of the subclass when constructing the parent class object. But it doesn't mean that you can't write programs that way, and the compiler won't report an error if you write the program that way. If you write this statement, the compiler will not call the implementation of the subclass, but will still call the implementation of the base class.

7. Do not call virtual functions in destructor. During the analysis, the sub-class destructor will be called first to parse the sub-class part of the object, and then the anti-constructor part of the base class will be called, if you call a virtual function in the destructor of the base class, it is very dangerous to call the function in the subclass object that has been destructed.

8. Remember to call the copy function of the base class to copy the part of the base class when writing the copy function of the derived class.

If a class is used as a base class, its fictitious function must be virtual, that is, the virtual keyword is used (the parameter is zero, it is a pure virtual function ).
Otherwise, there will be Memory leakage (very important), because when you use a base class pointer to delete an object of A derived class, you need to call the destructor of the derived class. However
The Destructor available for its subclass or sub-subclass can be a virtual function or a virtual function. (If the virtual keyword is not added, the derivation is not called.
Class destructor, and the preceding clxbase * Ptest = new clxderived; the statement is that the new clxderived object is not destroyed, resulting in Memory leakage)
2. virtual functions in a class. If a function in a class is declared as a virtual function, its subclass does not need to be declared as a virtual function (when the subclass has a subclass ),
It can also be declared as a virtual function. The result is the same. The truth of the virtual destructor is the same. Of course, it is not necessary to write all the class destructor.
Virtual function. Because when there is a virtual function in the class, the compiler will add a virtual function table to the class to store the virtual function pointer.
Will increase the storage space of the class. Therefore, only when a class is used as the base class can the Destructor be written as a virtual function.

Example:

# Include "iostream. H"

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 (){};
Virtual ~ Clxderived () {cout <"output from the destructor of class clxderived! "<Endl ;};

// Remove the virtual
Virtual void dosomething () {cout <"do something in class clxderived! "<Endl ;};

// Remove the virtual
};

Class clxthrived: Public clxderived
{
Public:
Clxthrived (){};
Virtual ~ Clxthrived () {cout <"output from the destructor of class clxthrived! "<Endl ;};

// Remove the virtual
Virtual void dosomething () {cout <"do something in class clxthrived! "<Endl ;}

// Remove the virtual
};
Void main ()
{
Clxbase * ptest1 = new clxbase;
Ptest1-> dosomething ();
Delete ptest1; // 1

Clxbase * ptest2 = new clxderived;
Ptest2-> dosomething ();
Delete ptest2; // 2 when the base class pointer is used to delete an object of A derived class

Clxderived * ptest3 = new clxderived;
Ptest3-> dosomething ();
Delete ptest3; // 3

Clxbase * ptest4 = new clxthrived;
Ptest4-> dosomething ();
Delete ptest4; // 4 when the base class pointer is used to delete an object of A derived class

Clxderived * ptest5 = new clxthrived;
Ptest5-> dosomething ();
Delete ptest5; // 5 when the base class pointer is used to delete an object of A derived class

Clxthrived * ptest6 = new clxthrived;
Ptest6-> dosomething ();
Delete ptest6; // 6
}

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.