[c ++虚拟类函数返回具体子类的实例

问题描述 投票:1回答:4

如果没有这种语法,但我本来会想要的是我想要的:

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,但也想知道更新的版本

c++ inheritance virtual
4个回答
3
投票

您尝试的解决方案有对象切片的风险。将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();
};

2
投票

似乎您正在尝试编写某种工厂或克隆函数。通常使用std::unique_ptr将创建对象的所有权干净地传递给调用方:

class A
{
   virtual std::unique_ptr<A> f() = 0;
};

class B : public A
{
   std::unique_ptr<A> f() override;
};

Demo

唯一的缺点是您无法让B::f返回std::unique_ptr<B>,因为它与std::unique_ptr<A>不协变(即使它隐式转换为它)。


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;
};

0
投票

写类似

class A
{
   virtual const A& f() const = 0;
};

class B : public A
{
   const B& f() const override { return *this; }
};

代替引用,您可以使用指针。

© www.soinside.com 2019 - 2024. All rights reserved.