C++中,子类会继承父类的虚函数表!对于父类的析构函数(虚函数) 也会继承吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++中,子类会继承父类的虚函数表!对于父类的析构函数(虚函数) 也会继承吗?相关的知识,希望对你有一定的参考价值。

一个子类继承了父类的虚函数表,而且父类的析构函数是虚函数,那么这个虚函数会放到父类的虚函数表中吗?子类继承时,这个虚函数表中是否有父类的析构函数?如果继承了这个父类的析构函数,那么子类的析构函数也是虚函数的时候,子类的虚函数是否会替换父类的虚函数。如果不替换,那么子类在使用调用析构函数时,是直接调用虚函数表中的子类析构函数吗?如果子类的的虚函数表中有父类的析构函数,看起来这个父类析构函数的存在似乎没有任何意义!!!……求大神解答!!!

上面的问题,楼上已经回答啦!我来说说这个意义吧!
如果子类的的虚函数表中有父类的析构函数,看起来这个父类析构函数的存在似乎没有任何意义!!
类是否需要一个虚析构函数?
如果一个类,有子类那么这个类就应该需要一个虚析构函数。虚函数也只有在继承的时候才会有用的。
说个例子:
class A
string t;
;
class B:A
string s;
;
int main()
A* bp=new B; //这句话是没有问题的吧!
delete bp; //但是这句话就会报错啦、除非你在A里面加上虚析构函数。
return 0;
这个就是他的意义吧!这个例子不是我原创的,来自《c++沉思录》
参考技术A 只要是父类的函数, 子类都会继承, 包括折构函数

而父类的函数是虚构函数的时候, 子类如果不重新定义该函数, 则正常继承. 否则覆盖了父类的盖函数

回到你的问题, 如果父类折构函数是虚函数, 子类继承的时候, 其折构函数首先默认是父类的折构函数, 如果子类重新定义了折构函数, 那就不再使用父类的, 但函数名字不变.

折构函数 是指 可以被子类重定义; 折构函数 是实现一个功能的函数. 2个层次不一样.追问

谢谢!……您的意思是当子类继承父类的虚析构函数时,子类的虚函数表中会有这个父类是析构函数 的,不过您说当子类重新定义虚析构函数时,子类不在使用父类的析构函数 的意思是 子类的虚函数表中 多了一项子类的虚函数地址还是说虚函数表中原来父类的虚函数地址 被子类的替代了???

参考技术B 不会自己创

用C++设计一个不能被继承的类(转)

在Java 中定义了关键字final,被final修饰的类不能被继承。

首先想到的是在C++中,子类的构造函数会自动调用父类的构造函数。同样,子类的析构函数也会自动调用父类的析构函数。要想一个类不能被继承,只要把它的构造函数和析构函数都定义为私有函数。那么当一个类试图从它那继承的时候,必然会由于试图调用构造函数、析构函数而导致编译错误。

可是这个类的构造函数和析构函数都是私有函数了,怎样才能得到该类的实例呢?可以通过定义静态来创建和释放类的实例。基于这个思路,可以写出如下的代码:

 1 ///////////////////////////////////////////////////////////////////////
 2 // Define a class which can‘t be derived from
 3 ///////////////////////////////////////////////////////////////////////
 4 class FinalClass1
 5 {
 6 public :
 7       static FinalClass1* GetInstance()
 8       {
 9             return new FinalClass1;
10       }
11  
12       static void DeleteInstance( FinalClass1* pInstance)
13       {
14             delete pInstance;
15             pInstance = 0;
16       }
17  
18 private :
19       FinalClass1() {}
20       ~FinalClass1() {}
21 };

 

这个类是不能被继承,但在总觉得它和一般的类有些不一样,使用起来也有点不方便。比如,只能得到位于堆上的实例,而得不到位于栈上实例。

能不能实现一个和一般类除了不能被继承之外其他用法都一样的类呢?办法总是有的,不过需要一些技巧。请看如下代码:

 1 ///////////////////////////////////////////////////////////////////////
 2 // Define a class which can‘t be derived from
 3 ///////////////////////////////////////////////////////////////////////
 4 template <typename T> 
 5 class MakeFinal
 6 {
 7       friend T;
 8  
 9 private :
10       MakeFinal() {}
11       ~MakeFinal() {}
12 };
13  
14 class FinalClass2 : virtual public MakeFinal<FinalClass2>
15 {
16 public :
17       FinalClass2() {}
18       ~FinalClass2() {}
19 };

 

这个类使用起来和一般的类没有区别,可以在栈上、也可以在堆上创建实例。尽管类MakeFinal<FinalClass2>的构造函数和析构函数都是私有的,但由于类FinalClass2是它的友元函数,因此在FinalClass2中调用MakeFinal<FinalClass2>的构造函数和析构函数都不会造成编译错误。

但当试图从FinalClass2继承一个类并创建它的实例时,却不同通过编译。

1 class Try : public FinalClass2
2 {
3 public :
4       Try() {}
5       ~Try() {}
6 };
7  
8 Try temp; 

 

由于类FinalClass2是从类MakeFinal<FinalClass2>虚继承过来的,在调用Try的构造函数的时候,会直接跳过FinalClass2而直接调用MakeFinal<FinalClass2>的构造函数。非常遗憾的是,Try不是MakeFinal<FinalClass2>的友元,因此不能调用其私有的构造函数。

基于上面的分析,试图从FinalClass2继承的类,一旦实例化,都会导致编译错误,因此是FinalClass2不能被继承。这就满足了设计要求。

C++11中已经有了final关键字:它的作用是指定类的虚函数不能被该类的继承类重写(override),或者是指定一个类成为一个不能被继承的类(final class)。

 1 struct A
 2 {
 3     virtual void foo() final;
 4 };
 5  
 6 struct B final : A
 7 {
 8     void foo(); // Error: foo cannot be overridden as it‘s final in A
 9 };
10  
11 struct C : B // Error: B is final
12 {
13 };

 

 

以上是关于C++中,子类会继承父类的虚函数表!对于父类的析构函数(虚函数) 也会继承吗?的主要内容,如果未能解决你的问题,请参考以下文章

为什么析构函数必须是虚函数?为什么C++默认的析构函数不是虚函数

如何能避免在调用子类对象的虚函数时调用父类的虚函数呢?

用C++设计一个不能被继承的类(转)

C++ 中,类的继承:父类当使用虚函数时候,子类对该函数进行重写的话,属于子类成员函数对虚函数的覆盖!

C++子类如何调父类的虚函数

C++——虚析构