具有 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
}
我有基地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
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
}