我感兴趣的是,是否可以从基类中定义的方法返回指向派生类的指针,而不将其显式地转换为派生类。我们的想法是接收器通过指向基类的指针接收指向派生类的指针,并将其视为通过多态实现的派生类。
例如,可以这样做:
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:我理解为什么这个特定的解决方案无法工作,如果有人知道解决问题的方法,而不是直接的方法,我感兴趣。
EDIT。我决定使用的解决方案在我上一篇评论中总结了接受的答案。
答案 0 :(得分:1)
首先,有协变的回归类型。这意味着,例如可以定义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
但是动态类型仍然是正确的派生类。这是有效的,因为成员函数的查找在实现该函数的大多数派生类中停止然后停止。所以基本上这是在基类中重写虚函数和隐藏函数的混合。
注意:
auto_ptr
(C ++ 98)或unique_ptr
(C ++ 11)会更好选择,因为没有共享参考。clone()
时,我还assert()
do_clone()
返回的指针非空,并且使用{this
指向与typeid
相同的动态类型{1}}。如果该断言触发,则有人忘记在派生类中覆盖do_clone()
。dynamic_cast
传递给您,我会将该决定留给您。我认为语法就像derived* derived_ptr = base_ptr->execute<derived>()
。