c++ - 多态和析构函数

标签 c++ destructor polymorphism

我刚刚写了一些代码,我试图理解对象是如何被多态性地破坏的。

#include <iostream>

struct Base {
    virtual ~Base() {
        std::cout << "base destructed\n";
    }
};

struct Derived : public Base{
virtual ~Derived() {
    std::cout << "derived destructed\n";
}
};

int main() {
  Derived der;
  Base bases1[2], bases2[2], bases3[2], bases4[2];
  //case 1
  new(bases1) Derived(der);
  std::cout << "((Base*)bases1)->~Base();\n";
  ((Base*)bases1)->~Base();
  //case 2
  new(bases2) Derived(der);
  std::cout << "\nbases2->~Base();\n";
  bases2->~Base();
  //case 3
  new(bases3) Derived(der);
  std::cout << "\nbases3[0].~Base();\n"; 
  bases3[0].~Base();
  //case 4
  new(bases4) Derived(der);
  std::cout << "\n(*bases4).~Base();\n";    
  (*bases4).~Base();

  getchar();
  return 0;
}

我对上述代码的了解:

  1. 在情况 1 中,bases1 指向派生对象的开头(包括一个 vptr),它是一个基指针,所以它就像我们在基指针上删除的通常情况(我的意思是销毁)。<
  2. 在case 2中,bases2是一个数组名,但在某些情况下我们可以将其视为指向第一个对象的指针,那么case 2应该给我和case 1相同的结果吗?
  3. 情况 3 和情况 4 相同,它们都取消引用第一个对象,类型为:Base,然后调用其析构函数。
  4. 这些代码是非标准的,而且很危险,但我只想弄清楚它是如何在指定的编译器(visual studio 2012)上工作的。

输出:

((Base*)bases1)->~Base();
derived destructed
base destructed

bases2->~Base();

bases3[0].~Base();
base destructed

(*bases4).~Base();
base destructed

我想知道的:

  1. 在情况 2 中,没有任何东西被破坏,可能的原因是什么?编译器优化?
  2. case 3,case 4,只有碱基被破坏,这是怎么回事?对象切片?

编辑:

以下是我从反汇编窗口中得到的:

 ((Base*)bases1)->~Base();
00D96CF9  mov         esi,esp  
00D96CFB  push        0  
00D96CFD  mov         eax,dword ptr [bases1]  
00D96D00  lea         ecx,[bases1]  
00D96D03  mov         edx,dword ptr [eax]  
00D96D05  call        edx  
00D96D07  cmp         esi,esp  
00D96D09  call        __RTC_CheckEsp (0D91992h)

  bases2->~Base(); //empty

  bases3[0].~Base();
00D96DB0  push        0  
00D96DB2  mov         eax,4  
00D96DB7  imul        eax,eax,0  
00D96DBA  lea         ecx,bases3[eax]  
00D96DBE  call        Base::`vector deleting destructor' (0D91A0Ah) //array delete?

  (*bases4).~Base();
00D96E14  push        0  
00D96E16  mov         eax,4  
00D96E1B  imul        eax,eax,0  
00D96E1E  lea         ecx,bases4[eax]  
00D96E22  call        Base::`vector deleting destructor' (0D91A0Ah)  //aray delete?

我看不懂汇编,有人能给我一个合理的解释吗?

最佳答案

new(bases1) Derived(der);

未定义的行为。 bases1 是一个Base 数组。将 Derived 类型的对象填充到其中没有任何意义。

关于c++ - 多态和析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17160264/

相关文章:

c++ - 使用接口(interface)从 dll 中导出类

c++ - 有没有办法让 C++ 析构函数急切地被调用?

java - 静态/编译时多态性

c# - 使用 new 关键字中断虚拟调用并再次启动新的虚拟层次结构

c++ - std::async - 依赖于实现的用法?

c++ - 如何在 C++ 中正确使用 ostringstream?

c++ - 错误 : enum was not declared in this scope

C++ 在范围结束前删除函数指针

c++ - 如果手动关闭程序,是否会调用析构函数?

haskell - 在 Haskell 中使用类型类访问相似数据类型的字段