zoukankan      html  css  js  c++  java
  • C++ 构造函数 析构函数 虚函数

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

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

    (1) 构造函数不能为虚函数

    让我们来看看大牛C++之父 Bjarne Stroustrup 在《The C++ Programming Language》里是怎么说的:

    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.

    --- From 《The C++ Progamming Language》15.6.2

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

    这就要涉及到C++对象的构造问题了,C++对象在三个地方构建:(1)函数堆栈;(2)自由存储区,或称之为堆;(3)静态存储区。无论在那里构建,其过程都是两步:首先,分配一块内存;其次,调用构造函数。好,问题来了,如果构造函数是虚函数,那么就需要通过vtable 来调用,但此时面对一块 raw memeory,到哪里去找 vtable 呢?毕竟,vtable 是在构造函数中才初始化的啊,而不是在其之前。因此构造函数不能为虚函数。

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

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

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

    class Expr {

    public:

         Expr();

         Expr(const Expr&);

         virtual Expr* new_expr() { return new Expr(); }

         virtual Expr* clone() { return new Expr(*this); }

    };

  • 相关阅读:
    HUST 1372 marshmallow
    HUST 1371 Emergency relief
    CodeForces 629D Babaei and Birthday Cake
    CodeForces 629C Famil Door and Brackets
    ZOJ 3872 Beauty of Array
    ZOJ 3870 Team Formation
    HDU 5631 Rikka with Graph
    HDU 5630 Rikka with Chess
    CodeForces 626D Jerry's Protest
    【POJ 1964】 City Game
  • 原文地址:https://www.cnblogs.com/jkred369/p/6743365.html
Copyright © 2011-2022 走看看