构造函数与析构函数能否为虚函数?

C + + C++ :构造函数和析构函数能否为虚函数?

简单回答是:构造函数不能为虚函数,而析构函数可以且常常是虚函数。

1.构造函数不能为虚函数

让我们来看看大牛 C + + C++ 之父 B j a r n e Bjarne S t r o u s t r u p Stroustrup 在《 T h e The C + + C++ P r o g r a m m i n g Programming L a n g u a g e Language 》里是怎么说的:

T o To c o n s t r u c t construct a n an o b j e c t object , a a c o n s t r u c t o r constructor n e e d s needs t h e the e x a c t exact t y p e type o f of t h e the o b j e c t object i t it i s is t o to c r e a t e create . C o n s e q u e n t l y Consequently , a a c o n s t r u c t o r constructor c a n n o t cannot b e be v i r t u a l virtual . F u r t h e r m o r e Furthermore , a a c o n s t r u c t o r constructor i s is n o t not q u i t e quite a n an o r d i n a r y ordinary f u n c t i o n function , I n In p a r t i c u l a r particular , i t it i n t e r a c t s interacts w i t h with m e m o r y memory m a n a g e m e n t management i n in w a y s ways o r d i n a r y ordinary m e m b e r member f u n c t i o n s functions d o n t don't . C o n s e q u e n t l y Consequently , y o u you c a n n o t cannot h a v e have a a p o n t e r ponter t o to a a c o n s t r u c t o r . constructor.

F r o m From T h e The C + + C++ P r o g a m m i n g Progamming L a n g u a g e Language 15.6.2 15.6.2

翻译:普通函数要构造一个对象,构造函数需要它要创建的对象的确切类型。因此,构造函数不能是虚函数。此外,构造函数并不是一个很普通的函数,特别是它与内存管理的交互方式与普通成员函数不同,因此,你不能拥有一个构造函数的桥接器。

然而大牛就是大牛,这段话对一般人来说太难理解了。那下面就试着解释一下为什么:

这就要涉及到 C + + C++ 对象的构造问题了, C + + C++ 对象在三个地方构建:

  • 函数堆栈
  • 自由存储区,或称之为堆
  • 静态存储区

无论在那里构建,其过程都是两步:首先,分配一块内存;其次,调用构造函数。好,问题来了,如果构造函数是虚函数,那么就需要通过 v t a b l e vtable 来调用,但此时面对一块 r a w raw m e m e o r y memeory (原始内存),到哪里去找 v t a b l e vtable 呢?毕竟, v t a b l e vtable 是在构造函数中才初始化的啊,而不是在其之前。因此构造函数不能为虚函数。

2.析构函数可以是虚函数,且常常如此

这个就好理解了,因为此时 v t a b l e vtable 已经初始化了;况且我们通常通过基类的指针来销毁对象,如果析构函数不为虚的话,就不能正确识别对象类型,从而不能正确销毁对象。

困惑我们的是我们却经常看到“虚构造函数”这样的说法,这就要归咎于不负责任或者说误人子弟的媒体了(包括书、技术文章等等)。因为他们说的是类似下面这样的做法:

class Expr {
public:
     Expr();
     Expr(const Expr&);
     virtual Expr* new_expr() { return new Expr(); }
     virtual Expr* clone() { return new Expr(*this); }
};

参考:C++:构造函数和析构函数能否为虚函数
更多解读:
为什么C++的构造函数不可以是虚函数,而析构函数可以是虚函数

猜你喜欢

转载自blog.csdn.net/qq_38790716/article/details/89480255