2015-03-02 115 views
0

我试图让我的头围绕在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) 

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

+3

能否请你使用你的榜样正确的语法:'栏(){市民:Foo'这是不正确的(有几个更像缺少返回类型和分号) – Borgleader 2015-03-02 16:16:03

+4

正在使'方法'虚拟一个选项?因为这是虚拟方法存在的确切原因。 – Guvante 2015-03-02 16:17:20

+0

要创建一个Bar对象,你不应该在变量名后面加上() - 编译器会认为你正在声明一个函数 - 这会让我时不时地发现 – Jimmy 2015-03-02 16:25:35

回答

1

请致电method,它会打电话给Bar::method()。是的,你可以这么做。它被称为多态性

为了达到这个目的,get_bar()需要返回一个指针,否则你会遇到slicing problem并且不会得到你正在寻找的多态行为。作为get_bar()是一个工厂函数将所有权转移给呼叫者优选返回一个智能指针像unique_ptrshared_ptr

​​

Foo::method()需要是为了覆盖它在Barvirtual。而为了摧毁Bar当正确的Foo指针被删除Foo必须有一个虚析构函数:

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

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

@Mike Seymour指出'C++ 11'编译器使用:'return std :: unique_ptr (new Bar);' – Gjan 2015-03-02 20:13:25

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的副本,它不会给你你想要的重载函数。

没有现有对象返回引用;所以你可能不得不动态地创建一个返回一个指针。除非你喜欢长时间的调试会话,使用智能指针来管理动态对象:如果我正确理解你的问题,你想get_bar()返回一个子类Bar,仿佛它是基类Foo,这样你可以随后

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