返回具体子类实例的 C++ 虚拟类函数
c++ virtual class function returning instance of concrete subclass
我想要什么,如果不使用此语法,而是在精神上:
class A
{
virtual A f()=0;
};
class B : public A
{
B f();
};
我确实看到了上面代码的问题:A 是虚拟的,因此无法创建 A 的实例,因此无法返回 A 的实例。
然而,A 的具体子类(例如 B(必须实现函数 f,它总是能够返回 themselve 的实例(例如 B 的实例(,即 A 子类的实例。
虽然上述内容不正确且无法编译,但有没有办法获得类似有效的东西? 可能,但不一定,类似
:class A
{
virtual "a concrete sublclass of A" f()=0;
};
注意:我不想返回指针或引用,因为我不希望 B 将自身的实例作为属性进行管理。
注意:如果可能的话,C ++ 11,但也很好奇听到更新的版本
您尝试的解决方案存在对象切片的风险。将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
的完整界面。我不清楚这是否是必需的。如果是,您将需要一个额外的层。例如,定义一个返回f()
调用的std::unique_ptr<B>
的g()
:
class B : public A
{
public:
std::unique_ptr<A> f() override { return g(); }
std::unique_ptr<B> g();
};
看起来您正在尝试编写各种工厂或克隆函数。这通常使用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>
不协变(即使它隐式转换为它(。
:如果可能的话,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;
};
写类似的东西
class A
{
virtual const A& f() const = 0;
};
class B : public A
{
const B& f() const override { return *this; }
};
您可以使用指针代替引用。
- 虚拟决赛作为安全
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- 如何在C++中获得"静态纯虚拟"功能?
- C++无法定义虚拟函数 OUTER 类和头文件
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 大小虚拟继承中的派生类
- 链接器找不到在虚拟类 c++ 中访问的静态字段的符号
- 使用 C++ 和 i2c 工具从虚拟 i2c 写入和读取
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 如果整个应用程序是虚拟映射的,为什么 new 会进行系统调用?
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- std::is_trivially_copyable_v 关于虚拟功能
- 删除C++继承中虚拟类成员的代码重复
- 子类地址等于虚拟基类地址?
- 当覆盖存在时调用基本虚拟"binded to object"函数
- 用于创建/注册虚拟存储设备的 IOKit 驱动程序
- 是否可以使用基类非虚拟方法中的派生类虚拟方法?