gpt4 book ai didi

c++ - 使用 std::vector 是否不如 std::vector> 安全?

转载 作者:行者123 更新时间:2023-11-30 01:17:01 26 4
gpt4 key购买 nike

假设我有一个简单的数据类:

struct Foo
{
int iData;
double dData;
};

我可以创建一个容器类,它可以实现为:

版本 1

struct Bar
{
std::vector<std::shared_ptr<Foo>> fooData;
};

或作为:

版本 2

struct Bar
{
Bar(){}

Bar(Bar const& copy)
{
for(auto fooPtr: copy.fooData)
{
fooData.push_back(new Foo(*fooPtr));
}
}

~Bar()
{
for(auto fooPtr: fooData)
{
delete fooPtr;
}
}

Bar& operator=(Bar const& rhs)
{
if ( this == &rhs )
{
return *this;
}

for(auto fooPtr: fooData)
{
delete fooPtr;
}
fooPtr.clear(); // Had missed this in the original code.

for(auto fooPtr: rhs.fooData)
{
fooData.push_back(new Foo(*fooPtr));
}

return *this;
}

std::vector<Foo*> fooData;
};

诚然,版本 1版本 2 更简单且更易于维护。但是,我有几个与代码的那个方面正交的问题。

  1. 从处理异常的角度来看,版本 1 是否比版本 2 更安全?
  2. 如果是,怎么做?

最佳答案

是的,第一个选项更安全。也就是说,您的复制构造函数有两个内存泄漏源,复制赋值运算符有内存泄漏并且完全是错误的。此外,第一个选项默认具有移动赋值和移动构造函数,从而提高了性能。 (如果你改用 std::unique_ptr 性能会更好)

Bar(Bar const& copy)
{
for(auto fooPtr: copy.fooData)
{
fooData.push_back(new Foo(*fooPtr));
//what happens if `new Foo` throws a bad_alloc?
//or if `Foo(const Foo&)` changes and now throws something?
//or if `fooData.push_back` throws a bad_alloc?
//anything you 'new'd is leaked.
}
}

Bar& operator=(Bar const& rhs)
{
if ( this == &rhs )
return *this;

for(auto fooPtr: fooData)
delete fooPtr;
//You forgot this line:
//fooData.clear();

for(auto fooPtr: rhs.fooData) //sharth notes you wrote copy.fooData but that's obvious
fooData.push_back(new Foo(*fooPtr));
//what happens if `fooData.push_back` throws a bad_alloc?
//the `Foo` you just created is leaked.

return *this;
}

关于c++ - 使用 std::vector<T*> 是否不如 std::vector<shared_ptr<T>> 安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25456408/

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