您的位置:首页 > 编程语言 > C语言/C++

构造函数不能声明为虚函数, 析构函数可以

2017-05-19 18:47 309 查看

构造函数不能声明为虚函数, 析构函数可以

在构造一个对象的时候,必须要知道对象的实际类型,而虚函数是在执行期才能确定实际的对象类型,在构造对象的时候,由于此时对象还没有构建成功,编译器无法知道该对象的实际类型,是该类本身还是该类的一个派生类

另外,虚函数都是通过虚函数表来调用的,而class object的虚函数表一般都是在构造函数中才会被赋值,即初始化vptr让它指向正确的虚函数表。那在构造期间,vptr还没有被初始化,故无法调用到虚函数。

根据上面的两点原因,故构造函数不能声明为虚函数

那么为什么析构函数通常就要设置为虚函数呢?

在类的继承中,如果有基类指针指向派生类对象,那么用基类指针delete时,如果不把析构函数定义成虚函数的话,那么就会直接释放base object部分,而派生类自己的那部分内容就无法释放掉,造成memory leak。

关于构造函数和析构函数的注意点:

如果我们定义了一个构造函数,编译器就不会再为我们生成默认构造函数了

编译器生成的析构函数是非虚的,除非是一个子类、其父类有个虚析构,此时的析构函数虚特性来自父类

有虚函数的类,几乎可以确定要有一个虚析构函数

如果一个类不可能是基类就不要申明析构函数为虚函数,虚函数需要额外的空间负担

析构函数的异常退出会导致析构函数执行不完全,从而会有内存泄漏的问题

在构造函数中不要调用虚函数。在基类构造的时候,虚函数式非虚,不会走到派生类中,既是采用的静态绑定。当我们构造一个子类的对象时,先调用基类的构造函数,构造子类中基类部分,子类还没有构造,还没有初始化,如果在基类的构造中调用了虚函数,那么就是调用一个还没有被初始化的对象,所以C++不可以在构造父类对象的时候调用子类的虚函数实现。如果你这么写的话就是调用的基类的函数实现而不是子类的函数实现。

在析构函数中也不要调用虚函数。在析构的时候会首先调用子类的析构函数,析构掉对象中的子类部分,然后调用基类的析构函数析构基类部分。如果在基类的析构函数里调用虚函数,会导致其调用已经析构了的子类对象里面的函数,这是错误的

在设计派生类的拷贝函数时,需要记住调用基类的拷贝函数来拷贝基类的部分。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息