C++ C++;:当非重写调用重写方法时会发生什么情况?

C++ C++;:当非重写调用重写方法时会发生什么情况?,c++,overriding,member-hiding,C++,Overriding,Member Hiding,被调用的重写方法的版本取决于 如果您想“通过”基类或“通过”派生类调用函数。然而,我发现如果我调用一个非重写的方法,并且重写的方法调用一些被重写的函数,那么基类版本仍然被调用,即使我是通过指向派生类的指针访问实例。有人能解释一下为什么会这样吗 代码: 类基{ 公众: 无效显示(){ foo(); } void foo(){ cout需要对需要重写的方法使用虚拟限定符。 前任: 阶级基础{ 公众: 无效显示(){ foo(); } 虚拟void foo(){ 库特 基类版本仍然被调用,即使我正在访

被调用的重写方法的版本取决于 如果您想“通过”基类或“通过”派生类调用函数。然而,我发现如果我调用一个非重写的方法,并且重写的方法调用一些被重写的函数,那么基类版本仍然被调用,即使我是通过指向派生类的指针访问实例。有人能解释一下为什么会这样吗

代码:

类基{
公众:
无效显示(){
foo();
}
void foo(){
cout
需要对需要重写的方法使用虚拟限定符。
前任:
阶级基础{
公众:
无效显示(){
foo();
}
虚拟void foo(){
库特
基类版本仍然被调用,即使我正在访问
实例通过指向派生类的指针。有人能解释一下吗
为什么会发生这种情况

虽然您通过指向派生类的指针调用方法,但您的方法不是虚拟的,所以使用静态分派,所以
Base::display()
直接调用
Base::foo()
,即使它在子类中被重写。要实现您想要的行为,您必须使用动态分派,即将您的方法标记为
virtual

class Base {
public:
    void display() {
        foo();
        bar();
    }
    void foo() {
        cout << "Base.foo()" << endl;
    }
    virtual void bar() {
        cout << "Base.bar()" << endl;
    }
};

class Derived : public Base {
public:
    void foo() {
        cout << "Derived.foo()" << endl;
    }
    virtual void bar() {
        cout << "Derived.bar()" << endl;
    }
};

int main() {
    Derived* derived = new Derived();
    derived->display();
}

问题是:您没有重写任何函数;您已经重写了

在C++中,只有虚拟函数(参见)可以重写。使基::()(虚拟)产生预期结果:())/P>
类基{
公众:
无效显示(){
foo();
}
虚拟void foo(){

cout您没有使用虚拟函数

类层次结构中的对象有两种类型:一种是“真实”类,另一种是编译器认为它拥有的类

调用虚函数时,编译器始终调用属于“实”类的函数。调用非虚函数时,编译器调用属于它认为是对象类的类的函数


在子类中执行代码时,编译器认为*这是子类的对象。因此,调用非虚拟函数将调用属于该子类的函数。

您没有重写这些函数,因为它们不是
虚拟的

virtual qualifier needs to be used for methods that need to be overridden.
ex:
 class Base {
public:
    void display() {
        foo();
    }
    virtual void foo() {
        cout << "Base.foo()" << endl;
    }
};

class Derived : public Base {
public:
    virtual void foo() {
        cout << "Derived.foo()" << endl;
    }
};

int main() {
    Derived* derived = new Derived();
    derived->display();
    while (true) {}
}
class Base {
public:
    void display() {
        foo();
        bar();
    }
    void foo() {
        cout << "Base.foo()" << endl;
    }
    virtual void bar() {
        cout << "Base.bar()" << endl;
    }
};

class Derived : public Base {
public:
    void foo() {
        cout << "Derived.foo()" << endl;
    }
    virtual void bar() {
        cout << "Derived.bar()" << endl;
    }
};

int main() {
    Derived* derived = new Derived();
    derived->display();
}
Base.foo()
Derived.bar()
class Base {
public:
    void display() {
        foo();
    }
    virtual void foo() {
        cout << "Base.foo()" << endl;
    }
};

class Derived : public Base {
public:
    void foo() {
        cout << "Derived.foo()" << endl;
    }
};

int main() {
    Derived* derived = new Derived();
    derived->display();
}