具有3级继承的基类shared_ptr的多态性

时间:2017-08-25 08:15:20

标签: c++ inheritance polymorphism smart-pointers

我有一个基类

class Base {
  public:
     virtual void func() = 0;
}

我有一个具体的派生类

class Derived : public Base {
  public:
     void func() {func2();}
     void func2() {};
}

最后,我有一个派生类

class DerivedDerived : public Derived {
      // inherits func() from Derived
      void func2() {} //Overrides func2() from Derived
}
void g(shared_ptr<Base> s) {
     s->func();
}

现在,我的问题是:我有一个函数g(),它接受一个shared_ptr&lt; Base&gt;并调用func()而不进行任何类型转换,因为它不知道任何子类。 现在,如果我这样做:

shared_ptr<Base> s1 = make_shared<Derived>();
shared_ptr<Base> s2 = make_shared<DerivedDerived>();
g(s1); //func() of Derived Class called
g(s2); //func2() of Derived Class called inside, func2() of DerivedDerived Class needed to be called inside.

我希望func()调用正确类的func2(),我...

2 个答案:

答案 0 :(得分:1)

作为本主题的补充,由于C ++ 11有override关键字,因此可以防止出现这类错误。当您使用它时,如果您没有覆盖使用该关键字的方法,则会抛出编译器错误。

class DerivedDerived : public Derived {
      void func2() {} override; // would throw an error in your case
}

答案 1 :(得分:0)

好了,因为你已经改变了代码 - 我正在更新结果,就像Jarod42提到的那样 - 你隐藏了func2而不是覆盖它。我还根据AlexanderS建议添加了覆盖关键字。

#include <iostream>
#include <memory>

class Base {
public:
    virtual void func() = 0;
};

class Derived : public Base {
public:
void func() override {func2();}
virtual void func2() {std::cout << "func2: Derived\n";};
}
;

class DerivedDerived : public Derived {
public:
     void  func2() override {std::cout << "func2: DerivedDerived\n";} //Overrides func() from Derived
};
void g(std::shared_ptr<Base> s) {
    s->func();
}

int main()
{
    std::shared_ptr<Base> s1 = std::make_shared<Derived>();
    std::shared_ptr<Base> s2 = std::make_shared<DerivedDerived>();
    g(s1); //func() of Derived Class called
    g(s2); //func() of Derived Class called, func() of DerivedDerived Class needed to
    return 0;
}

/***************
Output:
$ ./test
func2: Derived
func2: DerivedDerived
***************/

/* Compiler error when override is used and func2 is not marked virtual
   src/test.cpp:19:16: error: ‘void DerivedDerived::func2()’ marked ‘override’, but does not override
      void  func2() override {std::cout << "func2: DerivedDerived\n";} //Overrides func() from Derived
*/