using namespace std;
class A{
public:
A(){//A的构造函数,调用了虚构函数func
func();
}
void f(){//A的成员函数f,同样调用了虚构函数func
func();
}
virtual void func(){//虚构函数func,主要作用是输出A
cout << "A" << endl;
}
};
class B:public A{//B继承A
public:
B(){}//B的构造函数
void f(){//B的成员函数f,调用了虚构函数func
func();
}
virtual void func(){//虚构函数func,输出B
cout << "B" << endl;
}
};
int main(){
B b;
/定义B类对象,因为B继承自A,因此会首先调用A的默认构造函数。
//而A的构造函数中调用了虚函数func,会不会产生多态效果?结果却却不会
//这里输出: A
/
cout << "..........................................." << endl;
b.f();//b调用b的f函数,输出 "B"
b.A::f();
//b调用A的f函数(这里f函数不是虚函数,但是它调用了虚函数func),输出 "B"
//同样是同A的构造函数一样,同样是调用虚构函数,为啥输出不同?
//这里输出 "B"
cout << "..........................................." << endl;
A *pa = &b;
pa->f();//输出 "B"
pa->func(); //输出 "B"
cout << "..........................................." << endl;
return 0;
}
个人认为多态效应是在对象完整性情况下才会产生的,也就是对象实例已经构造完成。
创建派生类对象的时候,是先构造出基类的部分,然后再构造派生类的部分,当在基类构造函数里调用虚函数的时候,派生类尚未构造完成,其虚函数也没构造出来,也就是还没有这个函数。所以肯定是调用基类的虚函数
在调用构造函数中调用虚函数,编译器认为其类型是确定的,因此没有使用虚函数表,而是直接使用了函数地址。这点反汇编一下就能看出来。
构造完成后,虚函数表已经更新,因此这之后调用B类型的func()才是输出"B"。