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); }

    };

  • 相关阅读:
    监视和调整硬件性能
    ASP.NET MVC三个重要的描述对象:ActionDescriptor
    REST in Practice
    软硬件错误的排查之道
    OMCS 多媒体连接系统
    逻辑层 vs 物理层
    深入浅出裸测之道单元测试的单元化
    简单的网络爬虫实现
    WCF返回JSON与传入JSON(普通参数或对象)
    .NET程序员的一个礼物——TypeMonster
  • 原文地址:https://www.cnblogs.com/jkred369/p/6743365.html
Copyright © 2011-2022 走看看