C++中的多态性(意外行为)

Polymorphism in C++ (unexpected behaviour)

本文关键字:意外 多态性 C++      更新时间:2023-10-16

我有以下三个类:

class A
{
private:
std::string device;
public:
std::string getDeviceType() { return device; };
void setDeviceType(std::string device) { device = device; };
virtual void doSomething() = 0;
virtual void doSomething2() = 0;
};
class B: public A
{
private:
public:
B(){ ; };
virtual ~B(){ ; };
void doSomething() { std::cout << "I am usual B" << std::endl; };
void virtual doSomething2() { std::cout << "I am usual B" << std::endl; };
};
class C : public B
{
private:
public:
C(){ ; };
~C(){ ; };
void doSomething() { std::cout << "I am C" << std::endl; };
void doSomething2() { std::cout << "I am C" << std::endl; };
};

主要:

B *myHandler = new C();
myHandler->doSomething();
myHandler->doSomething2();

但是输出不如预期,我预期的输出是I am usual B然后I am C,因为doSomething()是类B的非虚拟成员。但真正的输出是I am C然后I am C.你知道为什么吗?

因为doSomething((是类B的非虚拟成员

这就是你错的地方。 在A中,您将doSomething()声明为virtual. 这意味着它在派生自它的类中隐式标记为虚拟。 所以doSomething()Bvirtual这意味着你会称CdoSomething()

原因是doSomething在类A中被标记为虚拟。因此,它在类BC中保持虚拟,因为它们继承自类A

由于此函数是虚拟的,因此根据对象的实际类型调用它,这在您的情况下是C,您将获得输出:I am C

一旦标记为虚拟,它在所有派生类中都保持虚拟状态。

在 C 语言中,你覆盖了 doSomething(( 和 doSomething2((。你实例化 C,所以在这两种情况下都会调用 C 的方法。

如果你省略了 doSomething(( 在 C 中的覆盖,输出将符合你的预期。

氪, 梅勒