动态绑定

要触发动态绑定必须满足两个条件:
1.只有指定为虚函数的成员函数才能进行动态绑定

2.必须通过基类类型的引用或者指针进行函数调用

-----摘自《C++ Primer》

 

对于第二点,我开始产生这样的疑问:

Q1:为什么只能是引用或指针,直接对象调用不可以吗?

Q2:为什么只能通过基类的引用或指针,而不能派生类的指针或引用?

 

A1:通过对象来调用,当赋值时候派生类对象赋值给基类时候,它们发生了类型转换了,当然不能动态绑定了;

     而通过指针和引用却可以,为什么,因为出现虚函数,编译器就为这个基类提供一张虚函数表,保存着派生类的地址,因此通过基类指针或引用操作可以实现动态绑定。

A2:这个更简单,假如基类能赋值给派生类,那当派生类指针调用它有的当基类没有的函数怎么办?所以编译器禁止这样赋值(我理解这种转换为类型的向上转换,

     向下转换可以通过,向下又称截断转换),所以用它来动态绑定。

下面是我的测试

class A{
public:
	A(){}
	virtual ~A(){}
	void dispaly()
	{
		std::cout<<"TEST A"<<std::endl;
	}
	virtual void dispalyEx()
	{
		std::cout<<"this is A called"<<std::endl;
	}
};

class B:public A{
public:
	B(){}
	~B(){}
	void dispaly()
	{
	    std::cout<<"TEST A"<<std::endl;
	}
	void dispalyEx()
	{
		std::cout<<"this is B called"<<std::endl;
	}

	void test()
	{
		std::cout<<"Test B~!"<<endl;
	}

};

对于上面两个类,这样调用时候能发生动态绑定:

 A *pa,a;
 B *pb,b;
 pa->dispalyEx();   //结果: this is A called
 pa = &b;
 pa->dispalyEx();  //结果:this is B called

 //而这样不能发生动态绑定:

 a.dispalyEx();  //结果: this is A called
 a=b;//截断转换  可以通过
 a.dispalyEx();  //结果: this is A called  不能动态绑定

 b = a;//编译出错 向上转换  编译器的错误信息提示  没有找到接受“A”类型的右操作数的运算符(或没有可接受的转换)

 pb = pa;同上

 

 

 

 

posted on 2010-07-30 17:15  Pro.Charm  阅读(1918)  评论(2编辑  收藏  举报

导航