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

时间:2015-10-25 19:49:35

标签: c++ method-overriding function-overriding member-hiding

被调用的重写方法的版本取决于 如果你关心调用函数"通过"基类或"通过"派生类。但是,我发现如果我调用一个非重写的方法,并且重写的方法调用了一些 重写的函数,那么仍然会调用基类版本,即使我通过指针访问实例到派生类。有人能解释为什么会这样吗?

CODE:

class Base {
public:
    void display() {
        foo();
    }
    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();
    while (true) {}
}

4 个答案:

答案 0 :(得分:4)

  

即使我正在访问基类版本,仍会调用基类版本   实例通过指向派生类的指针。有人可以解释一下   为什么会这样?

虽然通过指向派生类的指针调用方法,但是您的方法不是虚拟的,因此使用静态调度,因此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();
}

输出:

Base.foo()
Derived.bar()

答案 1 :(得分:1)

事情是:你没有覆盖任何功能;你有hidden its name

在C ++中,只能覆盖虚函数(参见C++ FAQ)。使 Base :: foo()虚拟产生预期结果:(run code!

<!DOCTYPE html>
    <html>
        <head>
            <title>My Webpage</title>
        </head>
    <body>
        <ul>
            {% for file in files %}
                <li>{{ file }}</li>
            {% endfor %}
        </ul>
    </body>
</html>

答案 2 :(得分:0)

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) {}
}

答案 3 :(得分:0)

您没有使用虚拟功能。

类层次结构中的对象有两种类型:它&#34; s&#34; real&#34; class,以及编译器在其拥有的那一刻所认为的类。

当你调用虚函数时,编译器总是调用属于&#34; real&#34;的函数。类。当您调用非虚函数时,编译器调用属于认为的对象类的类的函数。

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