从工厂返回时,可以正确的方法来upcast superty_ptr
Proper way to upcast unique_ptr when returning from a factory
我在1990年代学习了C ,但是从那时起就没有使用太多。我试图通过在工作中维护的一个小图书馆中使用现代技术来赶上过去几十年。我遇到了这个风格的问题,我想知道什么是现代共识。
我有一个纯虚拟基类Base
,有两个实现A
和B
。实现不在标题文件中;他们的公共API完全是Base
的一部分。我具有构造它们的工厂功能,需要调用一个共同的初始化器。这些课程不支持复制,并且可以在其一生中更改所有者,因此我使用unique_ptr
来保持更理智。
组合,这导致了一个尴尬的结构:
unique_ptr<Base> rv = make_unique<A>();
我尚未看到make_unique
明确给出模板类的情况。我还没有看到make_unique
不能与auto
一起使用的情况。但是,如果我希望RVO应用,则rv
(AFAICT(需要具有type 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;
}
再次,这是我为自己添加的一些限制,以使事情保持超级清洁:
- 由于
A
和B
类是实现细节,因此我不让它们外部可见。 - 因此,工厂功能需要返回
unique_ptr<Base>
而不是unique_ptr<A>
和unique_ptr<B>
。 - 我正在尝试使此NRVO友好,因为我还有其他只有移动的课程可以处理并希望练习使RVO友好的功能。
- 由于工厂功能必须调用
Initialize
方法,因此我必须返回lvalue。 - 出于通常的原因,我想使用
make_unique
而不是unique_ptr(new ...)
。
构造这种事情的通常方法是什么?
如果我希望RVO应用,则RV(AFAICT(需要具有type unique_ptr,而不是unique_ptr
由于您实际上没有返回或分配构造的对象(只是(唯一_(指针(,因此RVO在这里是无关紧要的。unique_ptr
基本上是零偏头,它是一个指针(即一个寄存器(。它可能会在C 抽象机器(STD :: simel_ptr的构造函数/操作员(方面有所不同,但实际上,这方面不会产生影响。
更重要的是:(移动(分配运算符或a或b的移动/复制构造函数,有或没有(n(rvo。
。请注意,这不是unique_ptr
特定的 - 如果要返回原始指针,则将适用相同的想法。
您的设计很好。尽管如此,如果您愿意消除返回时的移动/复制,即您的设计是这种情况(当然,如果您的编译器支持这种优化(,您可能还希望在Creation网站上消除它。为此,您需要使用
std::unique_ptr<Base> rv(new Derived(...));
在这里,您应该小心的位置而不是省略号。关于您的评论,new
的用法不愿在现代C 中使用。它不是内部使用new
的make_unique
,它是用现代C 编写的。
但是,再次,您的设计很好,只有在您真的想避免动作时,您才能诉诸我的建议。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 使用std::函数映射对象方法
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- C++从另一个类访问公共静态向量的正确方法是什么
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 没有为自己的结构调用列表推回方法
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 在类定义之后定义一个私有方法
- 枚举环境变量的惯用C++14/C++17方法
- 从工厂返回时,可以正确的方法来upcast superty_ptr