2009-12-25 59 views
1

对于下面的代码:两个调用析构函数

#include<iostream> 
#include<vector> 
#include<string> 
using namespace std; 

struct Test 
{ 

    string Str; 
    Test(const string s) :Str(s) 
    { 
     cout<<Str<<" Test() "<<this<<endl; 
    } 
    ~Test() 
    { 
     cout<<Str<<" ~Test() "<<this<<endl; 
    } 
}; 

struct TestWrapper 
{ 
    vector<Test> vObj; 
    TestWrapper(const string s) 
    { 
     cout<<"TestWrapper() "<<this<<endl; 
     vObj.push_back(s); 
    } 

    ~TestWrapper() 
    { 
     cout<<"~TestWrapper() "<<this<<endl; 
    } 
}; 

int main() 
{ 
    TestWrapper obj("ABC"); 
} 

这是我在我的MSVC++编译器得到的输出:

TestWrapper()0018F854
ABC测试()0018F634
ABC〜测试()0018F634
〜TestWrapper()0018F854
ABC〜测()003D8490

为什么re是两个对Test析构函数的调用,尽管只创建了一个Test对象。在两者之间是否有任何临时对象?如果是,为什么没有调用其相应的构造函数?

我错过了什么吗?

回答

6

您的输出不占测试的拷贝构造函数,这是std::vector易用。

您看到创建的测试对象是临时传递给push_back(),而不是实际在vector中。

2

我认为

vObj.push_back(s); 

涉及sTest隐式转换。所以实际发生的是

vObj.push_back(Test(s)); 

并且临时对象被复制到向量中后被销毁。

向量中的对象是使用复制构造函数构造的(而不是构造函数(const string s)),这就是为什么您看不到任何对应于析构函数调用的构造函数调用的原因。

+0

你说过“临时对象被复制到向量中后会被销毁”。 最后的析构函数调用是用于临时对象的。为什么不立即销毁? – 2009-12-25 06:42:41

+0

不,第一个析构函数调用是用于临时对象的。临时对象由一个字符串参数构造,这就是为什么你看到被调用的构造函数。 – Artelius 2009-12-25 06:50:20

+0

那么为什么“这个”类似的这两个值: ABC测试()0018F634 ABC〜测()0018F634 – 2009-12-25 07:32:46

2

尝试将一个拷贝构造函数的测试:

Test(const Test &obj) 
{ 
    cout<<obj.Str<<" Test() "<<this<<endl; 
    Str = obj.Str; 
} 

你会看到被称为拷贝构造函数为好,这个调用发生在对象被放置在矢量的时间。所以我们有两个对构造函数的调用和两个对析构函数的调用。