【问题标题】:Multiple template class destruction? [closed]多个模板类销毁? [关闭]
【发布时间】:2014-04-28 18:45:48
【问题描述】:

这是一个简单的测试:

#include <iostream>
#include <vector>

using namespace std;

class C
{
public:
    int _a;
    C(int a) { cout << "constructor C: " << (_a = a) << endl; }
    ~C()     { cout << "destructor C: "<< _a << endl; }
};

int main()
{
    vector<C> vec;

    for(int i=0; i<2; i++)
        vec.push_back(i+1);

    cout << "Go out --->\n";
    return 0;
}

输出:

constructor C: 1
destructor C: 1
constructor C: 2
destructor C: 1
destructor C: 2
Go out --->
destructor C: 1
destructor C: 2

当 C 是一个具有负责任的析构函数的真实类时,这看起来并不好笑。 有什么建议? 提前谢谢你。

【问题讨论】:

  • 与此处相同的问题 -> stackoverflow.com/q/2745350/476681
  • 你真的应该为像这样的非平凡类定义(或禁止!)一整套构造函数和赋值运算符;-)。然后您会看到(并正确实施)或禁止分配和复制您的对象,例如进出容器。 BЈовић 的链接说明了这些问题。
  • 有趣的是,我们对 1 有 3 个破坏,但对于 2“只有”两个。原因是向量通过重新分配而增长,从而复制了之前的元素(这里是 1)并破坏了旧的元素。如前所述,不记录复制,但记录破坏。啊,我明白了,弗拉德也做了同样的观察 :-)

标签: c++ vector destructor


【解决方案1】:

您会获得多个类析构函数日志,因为在向量中添加对象时存在对象副本。还登录复制构造器,您会看到它平衡了。如 cmets 所示,如果您使用的是 C++11,请同时登录移动构造函数。

这就是为什么如果对象构造是扩展的,你在向量中使用指针(smart_ptr)。或者保留足够的空间并使用 emplace_back(如果使用 C++11,则再次使用)。

【讨论】:

  • 或者可能是移动构造函数。
  • 移动构造函数会是更好的解决方案。
  • 如果他使用的是 C++11 是的。补充回答谢谢。
  • 为什么不直接reserve + emplace_back??
  • @billz 添加了您的建议。我们不知道他是否使用 C++11。
【解决方案2】:

构造函数 C: 1

用于创建临时对象 C( 1 ) 作为 vec.push_back(i+1) 的参数; 当 i =0

析构函数 C: 1

这个临时对象被复制到向量的一个对象中,然后被删除。

构造函数 C: 2

用于创建临时对象 C( 2 ) 作为 vec.push_back(i+1) 的参数; 当 i =1

向量需要分配一个新的内存区域来容纳第二个元素。所以它会重新分配内存并复制新内存中的第一个元素。

如果你要调用成员函数reserve

vector<C> vec;
vec.reserve( 2 );

那么就不会有重新分配,你也看不到下一个输出。

析构函数 C: 1

旧区内存中向量的第一个元素被删除

析构函数 C: 2

临时对象被复制到向量的一个对象中,然后被删除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-13
    • 2013-12-02
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-08
    • 2017-08-13
    • 1970-01-01
    相关资源
    最近更新 更多