zoukankan      html  css  js  c++  java
  • c++空指针调用类成员函数

    最近在看C++动态绑定问题时(理解静态绑定时)发现的问题:能用空指针调用类的成员函数(gcc,vs2013下都可以)。
    例子:

    class animal  {
    public:
        void sleep(){ cout << "animal sleep" << endl; }
        void breathe(){ cout << "animal breathe haha" << endl; }
    };
    class fish :public animal{
    public:
        void breathe(){ cout << "fish bubble" << endl; }
    };
    int _tmain(int argc, _TCHAR* argv[]){
        animal *pAn=nullptr;
        pAn->breathe();   // 输出: animal breathe haha
        fish *pFish = nullptr;
        pFish->breathe(); // 输出: fish bubble
        return 0;
    }  
    

    C++类的内存布局

    • 类的成员函数与成员对象内存中不放一起。
    • 对于类成员函数而言,此类的所有对象共用这个成员函数体,并不是一个对象对应一个单独的成员函数体。
    • 在类初始化的时候,编译器会将它的函数分配到类的外部,当然这也包括静态成员函数
    • 当程序被编译之后,此成员函数地址即已确定。

    这样的做法,主要是为了节约内存,这也是为什么静态函数可以在对象初始化之前运行的原因。

    C++类的this指针

    • 类的每个对象,都有一个指向自己的this指针,但不占用类对象空间(?)。
    • 这个指针的值,将会因为对象的不同而不同;
    • 它的作用主要就是用来区分不同的对象,同一个成员函数把类的各个对象的数据区别开。
      这样你就可以根据this来访问不同的对象的成员变量。

    编译器编译后的成员函数的第一个参数是this指针(最后一个参数?),通过this指针引用数据成员及调用其它成员函数。
    函数体内所有对类数据成员的访问, 都会被转化为this->数据成员的方式。

    c++空指针调用类成员函数

    为什么,因为在编译时对象就绑定了函数地址,和指针空不空没关系;

    pAn->breathe();编译的时候,函数的地址就和指针pAn绑定了;
    调用breath(*this),this就等于pAn。
    由于函数中没有需要解引用this的地方,所以函数运行不会出错,但是若用到this,因为this=nullptr,运行出错。

    这里对成员函数的解析,和查找其对应的代码的工作都是在编译阶段完成而非运行时完成的,这就是所谓的静态绑定,也叫早绑定。
    这是一个c++静态绑定的很好的例子,正确理解C++的静态绑定可以理解一些C++特殊情况下的行为。

    reference:
    http://www.zhihu.com/question/23260677
    http://www.unjeep.com/q/895161.htm
    http://segmentfault.com/q/1010000000611307
    http://blog.csdn.net/huangzeyy/article/details/7186792

  • 相关阅读:
    java调用打印机方式二
    java调用系统打印机
    Centos7开放端口(永久)
    java毫秒级别定时器
    java计算接口调用时间
    java实现当前时间往前推N小时
    java注解日志记录到数据库
    Java后端HttpClient Post提交文件流 及服务端接收文件流
    springboot整合websocket
    注解@Slf4j使用
  • 原文地址:https://www.cnblogs.com/iois/p/4979143.html
Copyright © 2011-2022 走看看