将子类返回到基类对象

时间:2015-03-02 16:14:26

标签: c++

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

考虑使用方法Foo()及其派生类method()的基类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)

这可能吗?如果,如何?我想我在这里犯了一个根本性的错误,我不明白。谢谢!

2 个答案:

答案 0 :(得分:3)

要覆盖(不覆盖)某个功能,它必须是虚拟的:

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

答案 1 :(得分:2)

如果我正确理解了您的问题,您希望get_bar()返回子类Bar,就好像它是基类Foo一样,以便您随后可以调用method它会调用Bar::method()。是的,你可以这样做。它被称为多态

为了实现此get_bar()需要返回指针,否则您将遇到slicing problem并且不会获得您正在寻找的多态行为。由于get_bar()是将所有权转移给调用者的工厂函数,因此最好返回类似unique_ptrshared_ptr的智能指针:

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

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

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

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