STL Vector是否调用了未分配对象的析构函数?

时间:2011-09-23 20:34:21

标签: c++ 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行按预期方式。这种行为是否正常?

(这是在FreeBSD系统上用GCC编译的)

3 个答案:

答案 0 :(得分:31)

一切都是应有的:有局部变量t,它会在main()的末尾被创建然后被销毁,而v[0]则会被创建和销毁main()的结尾。

您没有看到v[0]的创建,因为这是由您的测试类未提供的复制或移动构造函数发生的。 (因此编译器为您提供了一个,但没有输出。)


出于测试目的,一次性为自己编写包含所有可能的构造函数,析构函数,赋值和交换运算符的测试类并在每个编写器中打印诊断线是很方便的,因此您可以看到对象在使用时的行为方式容器和算法。

答案 1 :(得分: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 :(得分:2)

向量持有t的副本,因此在调用push_back之后,您有两个版本的t ...一个在堆栈上,一个在向量中。由于矢量版本是由copy-construtor创建的,因此你没有看到该对象的“Created ...”提示......但是当向量容器超出范围时它仍然必须被销毁,因此你得到两个“被摧毁......”的消息。