1

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

#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. 在情况 2 中,bases2 是一个数组名称,但在某些情况下我们可以将其视为指向第一个对象的指针,那么情况 2 应该给我与情况 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. 在情况 3 和情况 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?

我看不懂汇编程序,有人可以给我一个合理的解释吗?

4

1 回答 1

0
new(bases1) Derived(der);

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

于 2013-06-18T10:17:42.067 回答