gpt4 book ai didi

c++11 - 带有 std::vector 智能指针的深拷贝构造函数

转载 作者:行者123 更新时间:2023-12-02 01:49:28 29 4
gpt4 key购买 nike

假设我有一个 FooContainer 类,它聚合了 Foo 类型的 unique_ptr 对象

#include <vector>
#include <memory>

class FooContainer
{
protected:
std::vector<std::unique_ptr<Foo>> many;
//other attributes
public:
FooCoontainer(const FooContainer&);
//handling functions for Foo
};

问题是如何正确实现深拷贝构造函数,以及它的语法是什么。简单分配
FooContainer::FooContainer(const FooContainer& fc)
{
many=fc.many;

}

将尝试复制指针,并且(谢天谢地)编译器不允许使用 unique_ptr。所以我需要做这样的事情
FooContainer::FooContainer(const FooContainer& fc)
{
many.reserve(fc.many.size());
for(int i=0;i<fc.many.size();i++)
many.emplace_back(new Foo(*fc.many[i]));//assume that Foo has a copy constructor
}

这是这样做的方法吗?或者我应该使用shared_ptr而不是unique_ptr?

我还有一个额外的问题。
使用智能指针(以及上面代码中的保护)的原因是我派生了类 BarContainer,它聚合了许多对象 Bar,而这些对象又是 Foo 的子类。由于 Bar 的处理与 Foo 非常相似,与两个单独的类相比,这种方法将允许节省大量重复代码。

然而,。 BarContainer 的复制构造函数有问题。它将调用 FooContainer 的复制构造函数,它会变老并仅复制 Foo 部分而不是整个 Bar。更糟糕的是,任何调用 Bar 的虚拟方法都会调用 Foo 的版本。
所以我需要一种方法来覆盖这种行为。使复制构造函数成为虚拟是不可能的。
Bar 的复制构造函数也可以丢弃 Foo 复制构造函数的结果并执行正确的复制,但这非常低效

那么这个问题的最佳解决方案是什么?

最佳答案

Or may be I should use shared_ptr instead of unique_ptr?



这取决于您是需要深拷贝还是可以使用浅拷贝(意味着对一个的更改也将在另一个中可见)。

However,. the copy constructor of the BarContainer is problematic. It will the call copy constructor of FooContainer, that will go agead and copy only the Foo part instead of whole Bar.



通常的解决方法是给你的基类一个虚拟方法 clone :
class Foo {
public:
Foo(Foo&&) = default;
Foo& operator=(Foo&&) = default;
virtual ~Foo() = 0;
virtual std::unique_ptr<Foo> clone() const = 0;

protected: // or public if appropriate
Foo(const Foo&);
Foo& operator=(const Foo&);
};

class Bar : public Foo {
public:
virtual std::unique_ptr<Foo> clone() const;
};

std::unique_ptr<Foo> Bar::clone() const {
return make_unique<Bar>(*this);
}

如果 Foo 不是抽象的,它也会有 clone() 的实际实现。
FooContainer::FooContainer(const FooContainer& fc)
{
many.reserve(fc.many.size());
for (auto const& fptr : fc.many)
many.emplace_back(fptr->clone());
}

我使用了一个模板函数 make_unique ,它在 C++11 标准中被意外遗忘,但很快就会正式使用。如果您的编译器没有,则将自己的编译器放在某个头文件中很简单:
template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&& ... args) {
return std::unique_ptr<T>( new T(std::forward<Args>(args)...) );
}

(一起, unique_ptrmake_uniqueshared_ptrmake_sharedvector 完成了巨大的语言改进,这意味着您几乎不再需要低级和危险的关键字 0679104)

关于c++11 - 带有 std::vector 智能指针的深拷贝构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23716018/

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