如果不使用这种语法,我会想要的是精神,
class A
{
virtual A f()=0;
};
class B : public A
{
B f();
};
我确实看到了上面代码的问题:A是虚拟的,因此无法创建A的实例,因此无法返回A的实例。
但是,A的具体子类(例如B)必须实现函数f,该函数始终能够返回它们自己的一个实例(例如B的实例),即A的子类的实例。>
虽然以上内容不正确且无法编译,但有没有办法使类似的东西有效? 可能(但不一定)类似:
class A
{
virtual "a concrete sublclass of A" f()=0;
};
注意:我不希望返回指针或引用,因为我希望B不必将自身的实例作为属性来管理。
注意:如果可能的话,使用c ++ 11,但也想知道更新的版本
答案 0 :(得分:4)
您尝试的解决方案有对象切片的风险。将B
复制为A
可能无法达到您期望的方式。通常,在处理多态类型时,最好避免使用值语义。考虑返回std::unique_ptr<A>
:
#include <memory>
class A
{
public:
virtual std::unique_ptr<A> f()=0;
};
class B : public A
{
public:
std::unique_ptr<A> f() override;
};
这需要C ++ 11。它将按照您期望的方式运行,并且用户不必管理生成的对象的生存期。
但是,与原始代码中显示的相反,B::foo()
无法让您访问B
的完整界面。我不清楚是否需要这样做。如果是这样,您将需要一个额外的层。例如,定义一个g()
返回std::unique_ptr<B>
调用的f()
:
class B : public A
{
public:
std::unique_ptr<A> f() override { return g(); }
std::unique_ptr<B> g();
};
答案 1 :(得分:2)
您似乎正在尝试编写某种工厂或克隆函数。通常使用std::unique_ptr
来将创建对象的所有权干净地传递给调用方:
class A
{
virtual std::unique_ptr<A> f() = 0;
};
class B : public A
{
std::unique_ptr<A> f() override;
};
唯一的缺点是您无法让B::f
返回std::unique_ptr<B>
,因为它与std::unique_ptr<A>
并不协变(即使它隐式转换为它)。
答案 2 :(得分:1)
注意:如果可能的话,使用c ++ 11,但也想知道更新的版本
不。这是不可能的。不过,您可以在派生类中返回协变类型。
如果基类的返回类型为A&
,则可以在B&
中返回B
。
如果基类的返回类型为A*
,则可以在B*
中返回B
。
class A
{
virtual A& f()=0;
virtual A* g()=0;
};
class B : public A
{
B& f();
B* g()=0;
};
答案 3 :(得分:0)
写类似
class A
{
virtual const A& f() const = 0;
};
class B : public A
{
const B& f() const override { return *this; }
};
您可以使用指针代替引用。