关于虚函数
- C/C++ code
If the array member points to a Brass object,Brass::ViewAcct() is invoked; if the array member points to a BrassPlus object,BrassPlus::ViewAcct() is invoked. If Brass::ViewAcct() were been declared as virtual,Brass:ViewAcct() would be invoked in all cases.上面是c++ primer plus的原文
- C/C++ code
如果数组成员指向的是 Brass 对象,则调用 Brass::ViewAcct();如果指向的是 BrassPlus对象,则调用BrassPlus::ViewAcct().如果 Brass::ViewAcct()被声明为虚拟的,则在任何情况下都将被调用Brass::ViewAcct().上面是c++ primer plus中文版对应的内容
其中Brass是一个基类,BrassPlus是一个派生类。数组是Brass * p_clients[CLIENTS];
“如果 Brass::ViewAcct()被声明为虚拟的,则在任何情况下都将被调用Brass::ViewAcct().”
不明白这句话是什么意思?
因为作者在前几页说过,“如果使用了Virtual,则程序将根据引用或指针指向的对象的类型来选择方法”
“如果 Brass::ViewAcct()被声明为虚拟的,则在任何情况下都将被调用Brass::ViewAcct().”
“如果使用了Virtual,则程序将根据引用或指针指向的对象的类型来选择方法” ----那这两句话不是矛盾了吗
[解决办法]
试一下,再去分析。
[解决办法]
不申明为虚函数,在派生类中也可能被重写的。所以可能调用的是BrassPlus::ViewAcct();
[解决办法]
如果Brass::ViewAcct()被声明为虚拟的,则指向的是 BrassPlus对象调用BrassPlus::ViewAcct().如果BrassPlus::ViewAcct()没写,就去调用基类。
在对象为子类对象时,基类函数被定义为非虚拟的,子类的函数总是会覆盖基类的实现;定义为虚拟的,也是调用子类的。
其实你说的这种情况是Brass *pBrass; pBrass = new BrassPlus。定义为非虚时,只会调用基类的。
如果使用了Virtual,则程序将根据引用或指针指向的对象的类型来选择方法。书上说得是没错。这就是说的虚与非虚的区别。
如果BrassPlus *pBrass = new BrassPlus这样去做,就只会指向子类。
[解决办法]
- C/C++ code
#include <iostream>using namespace std;class A{public: void f1() { cout << "A---f1" << endl; } virtual void f2() { cout << "A---f2" << endl; }};class B:A{public: void f1() { cout << "B---f1" << endl; } void f2() { cout << "B---f2" << endl; }};void main(){ A a; B b; a.f1(); a.f2(); b.f1(); b.f2(); system("pause");}