返回更专门化对象的最佳方式
Best way to return more specialized object
我有一个具有多个子类的基类Base
,例如Child1
, Child2
等。在这个Base
类中,我有一个方法返回一个指向BaseDefinition
的指针:
virtual std::shared_ptr<BaseDefinition> GetDefinition() { return m_def; }
现在平行于Base
的类树,BaseDefinition
类也有子类:Child1Definiton
, Child2Definition
等。例如,Child1
的GetDefinition()
实现将返回std::shared_ptr<Child1Definition>
。
然而,GetDefinition()
的返回类型当然是std::shared_ptr<BaseDefinition>
,只要我们有Base*
指针,这也是完全正确的。但是假设我们有一个更特殊的指针,例如Child1*
,在这种情况下,Child1::GetDefinition()
的返回类型应该是std::shared_ptr<Child1Definition>
。一个人怎样才能达到这种行为呢?
类似如下:
struct BaseDefinition : std::enable_shared_from_this<BaseDefinition> {};
class Base
{
private:
virtual BaseDefinition* DoGetDefinition() = 0; // covariant return type
public:
std::shared_ptr<BaseDefinition> GetDefinition() {
return std::static_pointer_cast<BaseDefinition>(this->DoGetDefinition()->shared_from_this());
}
};
struct DerivedDefinition : BaseDefinition {};
class Derived : public Base
{
private:
virtual DerivedDefinition* DoGetDefinition() override = 0; // covariant return type
public:
std::shared_ptr<DerivedDefinition> GetDefinition() {
return std::static_pointer_cast<DerivedDefinition>(this->DoGetDefinition()->shared_from_this());
}
};
这里,DoGetDefinition()
是一个协变返回类型的私有虚函数。协变返回类型特性仅适用于普通指针或引用。虚函数可以被派生类重写,而不管它们的访问权限是什么(private/protected/public)。
GetDefinition
是它的公共非虚拟包装器,其唯一目的是将普通指针包装成智能指针。该函数由每个派生类定义。它隐藏了它的基类版本。
std::enable_shared_from_this
和shared_from_this()
需要在这里从shared_ptr<X>
到普通X*
,然后正确地返回到shared_ptr<X>
。
Derived a;
// Get Base stuff if accessing through Base.
Base* b = &a;
std::shared_ptr<BaseDefinition> p = b->GetDefinition(); // Calls Derived::DoGetDefinition
// Get Derived stuff if accessing through Derived.
Derived* d = &a;
std::shared_ptr<DerivedDefinition> q = d->GetDefinition();
相关文章:
- 在c代码之间共享数据的最佳方式
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 在reactor中存储eventHandlers的最佳方式是什么
- 在AVX通道中混洗的最佳方式
- 从 T 创建 std::future 的最佳方式<T>
- C++:使用 std::unique_ptr 访问重载运算符++的最佳方式?
- 对列表列表中的元素进行分组的最佳方式
- 利用 GPU 的最佳方式
- 使用 QT C++过滤大数据的最佳方式
- 算法设计:用边界数字表示 2D 网格的最佳方式,以C++?
- 在C++中共享键值对的最佳方式
- 为Catch2中的外部文本文件指定路径的最佳方式
- 代表Quarto棋盘游戏棋子的最佳方式
- 等待线程的最佳方式是什么
- 将uint8_t*buffer和size_tbufferlen从C++传递到C中的API函数的最佳方式是什么
- 创建控制台菜单C++的最佳方式
- 只显示片段着色器的最佳方式是什么
- 复制文件的最佳方式是什么,以便我可以在复制过程中轻松取消复制?