gpt4 book ai didi

c++ - std c++ 容器元素销毁和插入行为

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:13:20 24 4
gpt4 key购买 nike

我做了以下小程序:(基本上是一个检查它是否被创建、复制或销毁的类,以及一个执行其中一些操作的主类)

class Foo
{
public:
Foo(string name): _name(name)
{
cout << "Instance " << _name << " of Foo created!" << std::endl;
};
Foo(const Foo& other): _name(other._name)
{
cout << "Instance " << _name << " of Foo copied!" << std::endl;
};

~Foo()
{
cout << "Instance " << _name << " of Foo destroyed!" << std::endl;
}
string _name;
};



int main( int argc, char**argv)
{
Foo albert("Albert");
Foo bert("Bert");
{
vector<Foo> v1, v2;
system("PAUSE");

v1.push_back(albert);
system("PAUSE");

v2.push_back(bert);
system("PAUSE");

v1 = v2;
system("PAUSE");
}
system("PAUSE");
}

输出看起来像这样:

Instance Albert of class Foo created!
Instance Bert of class Foo created!
Press any key...
Instance Albert of class Foo copied!
Instance Albert of class Foo copied! // why another copy?
Instance Albert of class Foo destroyed! // and destruction?
Press any key...
Instance Bert of class Foo copied!
Instance Bert of class Foo copied!
Instance Bert of class Foo destroyed!
Press any key... // v1=v2 why did the albert instance not get destroyed?
Press any key...
Instance Bert of class A destroyed!
Instance Bert of class A destroyed!
Press any key... // there's still an albert living in the void

这让我觉得很奇怪。如果某样东西被复制了两次,我为什么还要费心把它作为引用传递呢?为什么 v1.operator=(other) 不破坏它包含的元素?它很适合 shared_ptr 的行为。谁能告诉我为什么?

添加我把它放在一个无限循环中并检查了内存使用情况,它似乎没有产生至少内存泄漏。

添加好的,mem 不是问题,因为它使用 operator= 而不是复制 ctor,好的,谢谢。当我添加

v1.reserve(10);
v2.reserve(10);

发生逻辑拷贝数。否则它会为每个 push_back 重新分配和复制整个 vector (我发现即使对于小 vector 也很迟钝)。看看这个,我会考虑更多地使用 .reserve 并优化我的赋值运算符 Like hell :)

补充:总结

  1. 所有这些问题似乎都是 VC++2005 特有的。
  2. 如果两个容器的大小匹配,我的实现使用 operator=元素而不是销毁旧元素并复制新元素,这似乎健全的做法。如果大小不同,则使用正常的销毁和复制。
  3. 随着 2005 年的实现,必须使用储备金!否则性能很差且不符合标准。
  4. 这些黑盒子比我想象的要黑得多。

最佳答案

Why do I even bother passing something as a reference if it gets copied twice anyway?

您应该将 STL 容器类型视为黑盒,可以根据需要随时复制您存储的对象。例如,每次调整容器大小时,将复制所有对象。

您的编译器对 push_back() 的实现可能使用了临时的额外拷贝。在我的机器上(Mac OS X 上的 gcc),push_back() 期间没有额外的拷贝(根据您程序的输出)。

此复制发生在 STL 代码中的某处,而不是在您的复制构造函数中(因为它使用引用)。

Why does the v1.operator=(other) not destroy the elements it contains?

Foo::operator= 将以“bert”实例作为参数为“albert”实例调用。因此,这里没有隐含的销毁和复制操作。您可能希望通过为运算符提供您自己的实现来验证这一点:

Foo& operator=(const Foo& other) {
cout << "Instance " << other._name << " of Foo assigned to " << _name << "!" << std::endl;
return *this;
}

这会在我的机器上产生以下输出:

Instance Albert of Foo created!
Instance Bert of Foo created!
Instance Albert of Foo copied!
Instance Bert of Foo copied!
Instance Bert of Foo assigned to Albert!
Instance Bert of Foo destroyed!
Instance Albert of Foo destroyed!
Instance Bert of Foo destroyed!
Instance Albert of Foo destroyed!

关于c++ - std c++ 容器元素销毁和插入行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1389402/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com