以前没有怎么注意C++继承时候基类引用子类或基类指针指向子类。现在写个小程序来测试下这种结果。
// TestCPP.cpp : Defines the entry point for the console application.
#include"stdafx.h"
#include"iostream"
using namespace std;
class B
{
public:
virtual void print()
{
cout<<"this is B"<<endl;
}
};
class A:public B //A类继承B类
{
public:
virtual void print()
{
cout<<"this is A"<<endl;
}
};
int _tmain(int argc,_TCHAR* argv[])
{
A a;
B b;
B &b1 = a; //基类引用子类
B *pb = &a; //基类指针指向子类
cout<<"a.print():" ;
a.print();
cout<<"b.print():" ;
b.print();
b =a ;
cout << "b =a b.print:";
b.print();
cout <<"b1.print():";
b1.print();
cout<<"pb->print():";
pb->print();
getchar();
return 0;
}
输出结果如下:
a.print():this is A
b.print():this is B
b =a b.print:this is B
b1.print():this is A
pb->print():this is A
我先从继承开始分析,因为A继承B。如下图:
注:虚函数指针,是一个隐藏的成员变量,这个隐藏的变量不会因为在拷贝构造函数中发生变化。
现在来分析以下语句:
b =a ; //用a对象构造函数b对象,在这个过程中只是调用拷贝构造函数,做数据成员的赋值,所以b对象的虚函数指针还是指向b对象的虚函数。
cout << "b =ab.print:";
b.print(); // b =a b.print:this is B
cout<<"b1.print():"; //b1是引用,也就是a对象内存地址的另一种叫法,所以b1指向的是a对象的内存地址
b1.print(); // b1.print():this is A
cout<<"pb->print():"; //所谓指针其实就是一个内存中存的是另个内存的地址,说白了也是一个变量,只是这个变量比较特殊,即pb变量存的是a对象内存的地址,
pb->print(); // this is A