基类返回指向派生类的指针,而无需在 C++ 中显式强制转换
Base class returning pointer to the derived class without explicit casting in c++
我感兴趣的是是否可以从基类中定义的方法返回指向派生类的指针,而无需将其显式转换为派生类。这个想法是,接收器通过指向基类的指针接收指向派生类的指针,并通过多态性将其视为派生类。
例如,可以这样做:
template<typename TClassType>
class A
{
public:
virtual std::shared_ptr<TClassType const> execute(void)
{
return std::shared_ptr<TClassType const>
(static_cast<TClassType*>(this));
}
};
在这里,派生类作为模板参数传递。
但是,我想做的是类似于这样的事情:
template<typename TBaseClassType>
class A
{
public:
virtual std::shared_ptr<TBaseClassType const> execute(void)
{
return this;
}
};
我想以这样一种方式来做到这一点,即返回的指向 base 的指针相对于原始派生类仍然是多态的。 TBaseClassType
可以是类A
,但也可以在类A
和继承树中的派生类之间,即 A->TBaseClassType->Derived
. Derived
是调用execute()
的类。
注1:它必须是指向const的指针(也可以是指向const的const指针)。
注2:我理解为什么这个特定的解决方案不起作用,如果有人知道解决问题的方法,而不是直接的方法,我很感兴趣。
编辑。我决定使用的解决方案总结在我的最后一条评论中,以获得可接受的答案。
首先,有协变返回类型。这意味着例如,可以定义一个clone()
函数来返回基类中的base*
,并在派生类中返回derived*
。但这不是您的问题,因为shared_ptr<base>
和shared_ptr<derived>
两种类型不是协变的,它们是完全不相关的。有一些方法可以解决这个问题,但它们需要一些工作:
class base
{
public:
smart_ptr<base> clone() const
{ return smart_ptr<base>(this->do_clone()); }
private:
virtual base* do_clone()
{ return new base(*this); }
};
如您所见,返回智能指针的公共函数调用返回原始指针且可以使用协变返回类型的私有虚拟函数。现在派生类:
class derived: public base
{
public:
smart_ptr<derived> clone() const
{ return smart_ptr<derived>(this->do_clone()); }
private:
virtual derived* do_clone()
{ return new derived(*this); }
};
这个类几乎包含类似的代码,只是它派生自base
。现在,如果您有指向派生类的引用(或指针/智能指针),则对其调用clone()
将为您提供正确类型的指针。在对基类的引用上调用它将为您提供一个指针,该指针的静态类型为 base
,但谁的动态类型仍然是正确的派生类。这是有效的,因为 memberfunction 的查找在实现该函数的最派生类中停止,然后停止。所以基本上这是覆盖虚函数和隐藏基类中的函数的混合体。
笔记:
- 我故意写了"smart_ptr",即使你写了shared_ptr,因为对于这个特定的例子,使用
auto_ptr
(C++98)或unique_ptr
(C++11)将是一个更好的选择,因为没有共享引用。 - 在实现
clone()
时,我还会assert()
do_clone()
返回的指针是非空的,并且它指向与使用typeid
this
相同的动态类型。如果触发该断言,则有人忘记在派生类中重写do_clone()
。 - 不能在基类中返回派生类型,因为这需要一个依赖循环,并且根本不确定基对象是否也是派生对象。
- 您可以创建一个模板函数,该函数将传递预期的类型,然后将其
dynamic_cast
到请求的类型,我将把这个决定留给您。然后语法会像derived* derived_ptr = base_ptr->execute<derived>()
,我想。
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 是否可以从int转换为enum类类型
- 了解 GLM- openGL 中的相机转换
- 将无符号char*转换为std::istream*C++