c++ virtual class 函数返回具体 subclass 的实例
c++ virtual class function returning instance of concrete subclass
我想要什么,如果不是用这个语法,但在精神上:
class A
{
virtual A f()=0;
};
class B : public A
{
B f();
};
我确实看到了上面代码的问题:A 是虚拟的,因此无法创建 A 的实例,因此无法 returned.
然而,A 的具体子类(例如 B)必须实现函数 f,它总是能够 return 自己的实例(例如 B 的实例),即 a 的实例A 的子类
虽然以上内容不正确且无法编译,但有没有办法让类似的内容有效?
可能但不一定是这样的:
class A
{
virtual "a concrete sublclass of A" f()=0;
};
注意:我不希望 return 指针或引用,因为我希望 B 不必将其自身的实例作为属性进行管理。
注意:如果可能的话,c++11,但也很想听听更新的版本
note: if possible c++11, but curious to hear about newer versions as well
没有。这是不可能的。不过,您可以 return 派生 class 中的协变类型。
如果baseclass中的return类型是A&
,那么B
中的returnB&
就可以了。
如果baseclass中的return类型是A*
,那么B
中的returnB*
就可以了。
class A
{
virtual A& f()=0;
virtual A* g()=0;
};
class B : public A
{
B& f();
B* g()=0;
};
写类似
class A
{
virtual const A& f() const = 0;
};
class B : public A
{
const B& f() const override { return *this; }
};
您可以使用指针代替引用。
您似乎正在尝试编写某种工厂或克隆函数。这通常是使用 std::unique_ptr
将创建的对象的所有权干净地传递给调用者来完成的:
class A
{
virtual std::unique_ptr<A> f() = 0;
};
class B : public A
{
std::unique_ptr<A> f() override;
};
唯一的缺点是你不能有 B::f
return a std::unique_ptr<B>
因为它与 std::unique_ptr<A>
不协变(即使它隐式转换为它)。
您尝试的解决方案存在对象切片风险。将 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()
,returns std::unique_ptr<B>
,f()
调用:
class B : public A
{
public:
std::unique_ptr<A> f() override { return g(); }
std::unique_ptr<B> g();
};
我想要什么,如果不是用这个语法,但在精神上:
class A
{
virtual A f()=0;
};
class B : public A
{
B f();
};
我确实看到了上面代码的问题:A 是虚拟的,因此无法创建 A 的实例,因此无法 returned.
然而,A 的具体子类(例如 B)必须实现函数 f,它总是能够 return 自己的实例(例如 B 的实例),即 a 的实例A 的子类
虽然以上内容不正确且无法编译,但有没有办法让类似的内容有效? 可能但不一定是这样的:
class A
{
virtual "a concrete sublclass of A" f()=0;
};
注意:我不希望 return 指针或引用,因为我希望 B 不必将其自身的实例作为属性进行管理。
注意:如果可能的话,c++11,但也很想听听更新的版本
note: if possible c++11, but curious to hear about newer versions as well
没有。这是不可能的。不过,您可以 return 派生 class 中的协变类型。
如果baseclass中的return类型是A&
,那么B
中的returnB&
就可以了。
如果baseclass中的return类型是A*
,那么B
中的returnB*
就可以了。
class A
{
virtual A& f()=0;
virtual A* g()=0;
};
class B : public A
{
B& f();
B* g()=0;
};
写类似
class A
{
virtual const A& f() const = 0;
};
class B : public A
{
const B& f() const override { return *this; }
};
您可以使用指针代替引用。
您似乎正在尝试编写某种工厂或克隆函数。这通常是使用 std::unique_ptr
将创建的对象的所有权干净地传递给调用者来完成的:
class A
{
virtual std::unique_ptr<A> f() = 0;
};
class B : public A
{
std::unique_ptr<A> f() override;
};
唯一的缺点是你不能有 B::f
return a std::unique_ptr<B>
因为它与 std::unique_ptr<A>
不协变(即使它隐式转换为它)。
您尝试的解决方案存在对象切片风险。将 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()
,returns std::unique_ptr<B>
,f()
调用:
class B : public A
{
public:
std::unique_ptr<A> f() override { return g(); }
std::unique_ptr<B> g();
};