先看一道题,题目为:
struct A{
void foo(){printf("foo");}
virtual void bar(){printf("bar");}
A(){bar();}
};
struct B:A{
void foo(){printf("b_foo");}
void bar(){printf("b_bar");}
};
再执行下面的代码:
A *p=new B;
p->foo();
p->bar();
输出为:
barfoob_bar
foobarb_bar
barfoob_foo
foobarb_fpp
答案选择第1个。
一般不建议在构造函数或者析构函数中调用虚函数,因为在构造函数和析构函数中调用虚函数不会呈现多态性。
原因是啥呢?你想啊,在构造基类调用基类的构造函数时,派生类的部分还没有构造,怎么可能能用虚函数实现动态绑定派生生类对象呢,所以构造B基类部分的时候,调用的基类的函数bar;
对于foo函数不是虚函数不会有动态绑定,所以调用的基类部分;对于第三个bar调用,是虚函数,实现动态绑定,所以调用的是派生类部分。
同样的道理,当调用继承层次中某一层次的类的析构函数时,往往意味着其派生类部分已经析构掉,所以也不会呈现出多态。
#include<iostream>
using namespace std;
class Base
{
public:
Base(int j):i(j){ }
virtual~Base(){}
void func1()
{
i *= 10;
func2();
}
int getValue()
{
return i;
}
protected:
virtual void func2()
{
i++;
}
protected:
int i;
};
class Child: public Base
{
public:
Child(int j): Base(j) {}
void func1()
{
i *= 100;
func2();
}
protected:
void func2()
{
i += 2;
}
};
int main()
{
Base *pb = new Child(1);
pb->func1();
cout<<pb->getValue()<<endl;
delete pb;
return 0;
}
输出为12,因为func2()并非在构造或析构函数里调用的。