2011-09-23 85 views
16

如下因素代码显示不期望的输出:STL Vector是否调用未分配对象的析构函数?

class test 
{ 
    public: 
    test() 
    { 
     std::cout << "Created" << (long)this << std::endl; 
    } 
    ~test() 
    { 
     std::cout << "Destroyed" << (long)this << std::endl; 
    } 
}; 

int main(int argc, char** argv) 
{ 
    std::vector<test> v; 
    test t; 
    v.push_back(t); 

    return EXIT_SUCCESS; 
} 

执行时它显示:

Created-1077942161 
Destroyed-1077942161 
Destroyed674242816 

我认为第二个“破坏”输出不应该存在。当我不使用该向量时,结果是一个Created和一个Destroyed行如预期。这种行为是否正常?

(这与GCC编译FreeBSD系统上)

+3

+1 [SSCCE](http://sscce.org/) – Flexo

+3

要打印指针,最好将其转换为void指针:'std :: cout <<(void *)this << std :: endl ;'。 –

+0

同时返回'EXIT_SUCCESS'是可选的。你可以在'main'中省略返回值,它会返回'0'(这将变成任何意味着你的平台的“正常终止”) –

回答

31

一切都是理所应当的:有局部变量t,这被创建,然后销毁在main()末,并有v[0],它得到在main()的末尾创建并销毁。

您看不到v[0]的创建,因为这是通过复制或移动构造函数(您的测试类未提供)来实现的。 (所以编译器提供一个给你,但没有输出。)


为了测试它的方便编写一次为自己和所有的测试类,它包含了所有可能的构造函数,析构函数,分配和交换运营商并在每个中打印诊断行,以便您可以目睹在容器和算法中使用对象时的行为。

+0

它不能是“移动构造函数”。 – Nawaz

+0

@Namaz:对。要使用移动构造函数,你必须说eitehr'v.push_back(std :: move(t))'或'v.push_back(test())'。不过,两者都会创建类似的消息序列。 –

29
#include <cstdlib> 
#include <vector> 
#include <iostream> 

class test 
{ 
    public: 
    test() 
    { 
     std::cout << "Created " << (long)this << std::endl; 
    } 
    test(const test&) 
    { 
     std::cout << "Copied " << (long)this << std::endl; 
    } 
    ~test() 
    { 
     std::cout << "Destroyed " << (long)this << std::endl; 
    } 
}; 

int main(int argc, char** argv) 
{ 
    std::vector<test> v; 
    test t; 
    v.push_back(t); 

    return EXIT_SUCCESS; 
} 

输出:

Created -1076546929 
Copied 147865608 
Destroyed -1076546929 
Destroyed 147865608 

std::vector::push_back复制t对象,你可以看到拷贝构造函数通过上面的代码中被调用。

2

该矢量持有t的副本,因此在拨打push_back后,您有两个版本的t ...一个在堆栈中,一个在向量中。由于矢量版本是由复制构造者创建的,因此您不会看到该对象的“创建...”提示...但它仍然必须在矢量容器超出范围时销毁,因此您得到两个“被毁坏......”的消息。

相关问题