gpt4 book ai didi

c++ - 将 unique_ptr 的内容复制到未知派生类

转载 作者:行者123 更新时间:2023-11-28 01:35:41 27 4
gpt4 key购买 nike

我有一个抽象基类,有几个具体的派生类;这些类都不管理任何资源。

#include <memory>
#include <vector>

// this is a pure abstract class that contains no resources
class Base {
public:
Base() {};
virtual int doSomething() = 0;
};

class Derived : public Base {
public:
Derived() {};

// this mutates the derived class
int doSomething() override { return 0; };
};

class Derived2 : public Base {
public:
Derived2() {};

// this mutates the derived class
int doSomething() override { return 0; };
};

我有一个返回随机派生实例(Derived1、Derived2、Derived3,取决于随机数抛出)的函数。

std::unique_ptr<Base> randomDerivedInstance() {
// pick a random number here and return Derived1 or Derived2 etc.
// for the purpose of this problem, I'm just returning a fixed derived class
return std::make_unique<Derived>();
}

我有一个结构,我想将这个派生实例存储在

struct DataStruct {

// this can contain Derived1 or Derived2
std::unique_ptr<Base> base;

// other things in struct omitted for clarity

// obviously this won't work
DataStruct(std::unique_ptr<Base> base) : base(base) {};
};

我从我的随机函数返回一个唯一的指针,并想将一个拷贝保存到结构中,然后调用 doSomething 对类内部执行几个变异操作,但我没有不希望它们影响存储在列表中的拷贝。

如果我知道派生实例的类型,我会使用复制构造函数创建一个新实例并将其添加到 vector 中,但在这种情况下我不知道我正在尝试的实例的具体类型添加,所以我不知道要使用哪个特定的构造函数。

int main() {
// I want to create a vector of random instances
std::vector<DataStruct> list;

// I create a random instance
auto myDerived = randomDerivedInstance();

// and I want to push a copy of myDerived before I do something with it
// obviously this doesn't work because its a unique_ptr
// what can I do here?
list.push_back(DataStruct(myDerived));

// do something that mutates myDerived
myDerived->doSomething();

// I don't want my mutations to myDerived to affect the list copy


}

由于明显的原因,上面的代码没有编译,因为我试图在 DataStruct 构造函数中分配一个 unique_ptr

为了使其按预期工作,我需要对此架构和代码进行哪些更改?即,将随机派生实例的值拷贝添加到结构中,以便我可以改变原始实例(反之亦然,添加原始实例并改变拷贝)。

提前感谢所有帮助!

最佳答案

在类Base中添加一个虚成员函数clone:

virtual auto clone() const
-> std::unique_ptr<Base>
= 0;

在每个派生类 Derived 中覆盖它以提供派生类特定的克隆:

auto clone() const
-> std::unique_ptr<Base>
override
{ return std::unique_ptr<Base>( new Derived{ *this } ); }

有可能以更高级的方式执行此操作,如果您在编译时知道派生程度最高的类,则可以静态地获得该类型的克隆,但看起来您并不需要它。

免责声明:现成的代码,未经编译器审查。


很久以前,clone 函数被称为虚拟构造函数,这个术语在 the FAQ item about this 中使用过。 .我认为它是由 Coplien 引入的。当前的常见问题解答文本没有说明。


同样值得注意的是:在 C++11 及更高版本中,clone 函数实现的生成可以通过 Derived 继承自一个实现而部分自动化,而该实现又继承自 Base,带有构造函数参数的转发。

C++03 不支持转发,因此不得不使用代码生成宏(邪恶但实际上是当时唯一真正的解决方案)、通过虚拟继承层次结构中的支配实现继承(极其复杂和丑陋的),或者像我们现在在 C++11 及更高版本中做的那样,但使​​用 Do-It-Yourself 参数转发方案(有点任意限制)。

有关这些旧 C++03 技术的概述,请参阅我 2010 年的博客文章“3 ways to mix in a generic cloning implementation ”。

关于c++ - 将 unique_ptr 的内容复制到未知派生类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49355456/

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