zoukankan      html  css  js  c++  java
  • 动态绑定

    要触发动态绑定必须满足两个条件:
    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;同上

    点击这里给我发消息
  • 相关阅读:
    分布式锁设计方案
    ACID/CAP/BASE 理论知识
    分布式ID设计方案
    perl代码调试
    文档型数据库设计模式-如何存储树形数据 [转]
    树形结构的数据库表Schema设计
    http协议相关
    HTTPS加密原理(转)
    VBA读写XML文件
    VBA 刷新数据透视表
  • 原文地址:https://www.cnblogs.com/charm/p/1788908.html
Copyright © 2011-2022 走看看