gpt4 book ai didi

c++ - 从工厂返回时向上转换 unique_ptr 的正确方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:06:21 29 4
gpt4 key购买 nike

我在 1990 年代学习了 C++,但从那以后就没怎么用过了。我试图通过在我维护的一个小型图书馆中使用现代技术来 catch 过去几十年的工作。我遇到过这个文体问题,我想知道什么是现代共识。

我有一个纯虚基类Base , 有两个实现 AB .实现不在头文件中;他们的公共(public) API 完全是 Base 的一部分.我有工厂函数来构造它们,需要调用一个通用的初始化程序。这些类不支持复制,并且可以在其生命周期内更改所有者,所以我使用 unique_ptr让事情更加理智。

结合起来,这导致了一个有点尴尬的结构:

unique_ptr<Base> rv = make_unique<A>();

我还没有看到 make_unique 的案例明确地给定了一个模板类。我也没有看到 make_unique 的案例不能与 auto 一起使用.但是,如果我想申请 RVO,那么 rv (AFAICT) 需要有类型 unique_ptr<Base>而不是 unique_ptr<A> .

在这里,我在一行中与“我以前看到的”有两个偏差。这在我脑海中竖起旗帜,让我觉得我应该向社区征求集体智慧。

好的,足够的英语;这是一些代码:

class Base {
public:
static std::unique_ptr<Base> MakeA();
static std::unique_ptr<Base> MakeB();
private:
void Initialize();
};

class A : public Base {};
class B : public Base {};

std::unique_ptr<Base> Base::MakeA() {
std::unique_ptr<Base> rv = std::make_unique<A>();
rv->Initialize();
return rv;
}

std::unique_ptr<Base> Base::MakeB() {
std::unique_ptr<Base> rv = std::make_unique<B>();
rv->Initialize();
return rv;
}

同样,这里是我为自己添加的一些限制,以保持事情 super 干净:

  • 自上课以来 AB是实现细节,我不会让它们对外可见。
  • 因此,工厂函数需要返回一个unique_ptr<Base>。而不是 unique_ptr<A>unique_ptr<B> .
  • 我正在努力使这个 NRVO 友好,因为我还有其他仅移动类要处理并且想练习制作 RVO 友好的函数。
  • 因为工厂函数必须调用 Initialize方法,我必须返回一个左值。
  • 我想使用 make_unique而不是 unique_ptr(new ...) , 对于 the usual reasons .

构造这种东西的通常方法是什么?

最佳答案

if I want RVO to apply, then rv (AFAICT) needs to have type unique_ptr rather than unique_ptr

由于您实际上并没有返回或分配构造的对象(只是指向它的 (unique_)pointer),因此 RVO 在这里无关紧要。 unique_ptr 基本上是零开销,它是一个指针(即一个寄存器)。它可能在 C++ 抽象机(std::unique_ptr 的构造函数/运算符)方面有所不同,但实际上这方面不会产生影响。

更重要的是:在任何时候都不会调用(移动)赋值运算符或 A 或 B 的移动/复制构造函数,无论是否使用 (N)RVO。

请注意,这并非特定于 unique_ptr - 如果您要返回原始指针,同样的想法也适用。

关于c++ - 从工厂返回时向上转换 unique_ptr 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49667276/

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