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

Polymorphism with shared_ptr of base class with 3 level inheritance

我有基地class

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

我有一个具体的派生class

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

最后,我有一个派生class

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 并在没有任何类型转换的情况下调用 func() 因为它不知道任何子 class es。 现在,如果我这样做:

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() 调用正确 class 的 func2(),我..

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

#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
*/

作为本主题的补充,自 C++11 以来,有 override 关键字,可以防止此类错误。当你使用它时,如果你没有覆盖你使用关键字的方法,它会抛出一个编译器错误。

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