被调用的重写方法的版本取决于 如果你关心调用函数"通过"基类或"通过"派生类。但是,我发现如果我调用一个非重写的方法,并且重写的方法调用了一些 重写的函数,那么仍然会调用基类版本,即使我通过指针访问实例到派生类。有人能解释为什么会这样吗?
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) {}
}
答案 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是子类的对象。因此,调用非虚函数将调用属于该子类的函数。