将子类返回到基类对象中

Return child class into base class object

本文关键字:对象 基类 子类 返回      更新时间:2023-10-16

我正试图解决C++中的一些继承问题:

考虑具有方法method()的基类Foo()及其派生类Bar。现在我覆盖Bar中的方法。

class Foo{
public:
    double method();
}
class Bar public: Foo
{
public:
    double method()
}

还有这样一个函数:

Foo get_bar(){
    Bar bar()
    return bar
}

调用函数get_bar()我希望能够调用Bar::method()

Foo foo = get_bar();
foo.method() (-> which should be Bar::method)

这可能吗?如果,如何?我认为我在这里犯了一个根本性的错误,我没有看到。谢谢

要覆盖(而不是覆盖)一个函数,它必须是虚拟的:

class Foo {
public:
    virtual void method();
    virtual ~Foo() = default;  // technically optional, but usually needed
};

为了完整起见,以下是派生类的正确语法:

class Bar : public Foo {
public:
    void method() override;  // override is optional, but a good idea
};

多态性只适用于引用和指针,所以函数必须返回其中一个,而不是基类对象。照原样(一旦语法固定),它切片Bar对象以返回其Foo的副本,这将不会给您所需的重写函数。

没有可返回引用的现有对象;因此,您可能需要动态地创建一个返回指针。除非您喜欢长时间的调试会话,否则请使用智能指针来管理动态对象:

std::unique_ptr<Foo> get_bar() {
    return std::unique_ptr<Foo>(new Bar); // C++14: make_unique<Bar>();
}

如果我正确理解你的问题,你希望get_bar()返回一个子类Bar,就像它是基类Foo一样,这样你就可以在它上面调用method,它也会调用Bar::method()。是的,你可以做到。它被称为多态性

为了实现这一点,get_bar()需要返回一个指针,否则您将遇到切片问题,并且无法获得您想要的多态行为。由于get_bar()是一个将所有权转移给调用者的工厂函数,因此最好返回像unique_ptrshared_ptr:这样的智能指针

std::unique_ptr<Foo> getBar() {
    return std::make_unique<Bar>();
}

Foo::method()需要是virtual才能在Bar中覆盖它。为了在删除Foo指针时正确销毁BarFoo必须有一个虚拟析构函数:

class Foo {
  public:
    virtual void method();
    virtual ~Foo(){}
};
class Bar : public Foo {
  public:
    void method() override;
};