构造函数和析构函数能否是虚函数

1.构造函数能否是虚函数呢?答案当然是否定的!

C++之父 Bjarne Stroustrup 在《The C++ Programming Language》(chapter 15.6.2)里是这么说的:

To construct an object, a constructor needs the exact type of the object it is to create. Consequently, a constructor cannot be virtual. Furthermore, a constructor is not quite an ordinary function, In particular, it interacts with memory management in ways ordinary member functions don't. Consequently, you cannot have a ponter to a constructor.


简单解释就是要构造一个对象,就必须确切知道所创建的对象的具体类型,假如构造函数是虚函数,那么我们就得通过虚函数表vtable来调用构造函数了,然而虚函数表是在构造函数中才初始化的,所以通过这种方式我们不可能得到构造函数的指针,所以构造函数不能是虚函数。

但是如果我们实在是作,实在是想实现这种“虚构造函数”效果,有没有办法呢?办法是有的,那就是定义一个虚函数,由它来调用构造函数并返回构造起来的对象;

例如:

</pre><p><pre name="code" class="cpp">class Base {
public:
	Base();
	Base(const Base&);
	vitural Base* new_operator {return new Base();}
	vitural Base* clone() {return new Base(*this);}
	//...
};

class Derived : public Base {
public:
	Derived();
	Derived(const Base&);
	vitural Derived* new_operator {return new Derived();}
	vitural Derived* clone() {return new Derived(*this);}
	//...
};

void user(Base* p)
{
	Base* p2 = p->new_operator(); //P2的类型是未知的;
}


2.析构函数可以是虚函数,因为此时虚函数表vtable已经初始化了,而且我们通常是通过基类的指针来销毁派生类对象,如果析构函数不为虚函数的话,就不能正确识别对象类型,也就不能正确销毁对象了;如果基类的析构函数不是虚函数,则delete一个指向派生类对象的基类指针将产生未定义的行为;还有一点需要注意的是,如果一个类定义了虚析构函数,那么编译器将不会为这个类合成移动操作;


猜你喜欢

转载自blog.csdn.net/Dr_Neo/article/details/52141793