代码之家  ›  专栏  ›  技术社区  ›  kdog

基类子类中具有虚拟析构函数的默认析构函数

  •  9
  • kdog  · 技术社区  · 8 年前

    我有一个基本类 A 使用虚拟析构函数。 A. 有子代 B C 使用默认析构函数。删除的对象是否安全 C 通过指向 A. ?

    更具体地说,请考虑以下示例代码:

    class A {
     public:
          A(){};
          virtual ~A() {/* code here */};
     };
     class B: public A {
          B() {/* code....*/};
          /* NO DESTRUCTOR SPECIFIED */
       };
     class C: public B {/*same as above, no destructor */};
     class D: public B {/* same as above, no destructor*/}
    

    要运行的代码如下所示:

    A* getAPointer(void); /* a function returning a C or a D*/
    A* aptr=getAPointer();
    /* aptr is declared as A*, but points to either an object of class C 
      or class D*/
    delete aptr;
    

    delete aptr 安全它是否做了正确的事情:如果 aptr 指向类的对象 C 这个 aptr 第一次通话 C 的析构函数 B 的析构函数 A. 的析构函数?

    3 回复  |  直到 8 年前
        1
  •  12
  •   Edgar Rokjān    8 年前

    通过指向的指针删除C的对象是否安全?

    是的,它是完全安全的,因为类中的所有析构函数 B , C D 将隐式虚拟。

    发件人:

    15.4析构函数[dtor类]

    10可以将析构函数声明为虚拟(13.3)或纯虚拟(13.4); 如果在 程序,应定义析构函数。 如果类有基类 对于虚拟析构函数,其析构函数(无论是用户还是 隐式声明)是虚拟的。

    A 有一个虚拟析构函数,然后 B C , D 分别具有虚拟析构函数和:

    delete aptr;
    

    工作正常。

        2
  •  3
  •   Christian Hackl    8 年前

    是的,很安全。正在添加 virtual 对于派生类的析构函数来说是多余的。

    考虑该机制是如何工作的。什么时候 delete 使用时,运行时需要知道销毁链应该从哪个析构函数开始。如果 删去 操作数具有 事实上的 析构函数,那么运行时就可以知道它必须付出额外的努力并检查动态类型了。

    在您的示例中,它发现动态类型为 C 所以 C::~C 被调用。 C: :~ C 自动导致 B::~B 这会自动导致 A::~A .

    要求 C 的(或 B 的析构函数 事实上的 将毫无意义。毕竟,运行时必须找出动态 C 在以下情况下键入 A: :~ A 事实上的 . 在这一点上,它不在乎 C: :~ C 事实上的 或者不是。这会有什么不同?

        3
  •  0
  •   jfMR    8 年前

    删除的对象是否安全 C 通过指向 A ?

    对自从 A. 的析构函数为 事实上的 , C 将调用的析构函数。这仅仅是由于 动态调度 作品