• c++成员函数的存储方式


    原创博客:转载请标明出处:http://www.cnblogs.com/zxouxuewei/

    成员函数属于一个类的成员,出现再类体中。可以被指定为公有,私有或受保护的。

    1.在类外面定义成员函数时,需要用类名加作用域限定符(::),如下代码:

    复制代码
    #include <iostream>
    #include <string>
    using namespace std;
    
    class _test_myclass
    {
    public:
        void display(const int &value);  //在类内声明成员函数
    }class1;
    
    void _test_myclass::display(const int &value) //在类外定义成员函数,用作用域操作符
    {
        cout << "value is "<<value<<endl;
    }
    
    int main(int argc,const char* argv)
    {
    
        class1.display(100);
        return 0;
    }
    复制代码

    2.inline成员函数

    inline成员函数为内敛函数(也叫内置函数),在类内定义的成员函数可以不用加inline关键字。因为类内成员函数默认为内置函数。

    复制代码
    #include <iostream>
    #include <string>
    using namespace std;
    
    class _test_myclass
    {
    public:
        void display(const int &value)   //类内成员函数无需添加inline关键字
        {
            cout << "value is "<<value<<endl;
        }
    
    }class1;
    
    inline void display2(const int &value)   //声明为内置函数
    {
       cout << "value is "<<value<<endl;
    }
    
    int main(int argc,const char* argv)
    {
    
        display2(100);
        return 0;
    }
    复制代码

    3.成员函数的存储方式

    用类去定义对象时,系统会为每一个对象分配存储空间。如果一个类包括了数据和函数,要分别为数据和函数的代码分配存储空间。

    按理说,如果用同一个类定义了10个对象,那么就需要分别为10个对象的数据和函数代码分配存储单元,如图8.4所示。

    图8.4

    能否只用一段空间来存放这个共同的函数代码段,在调用各对象的函数时,都去调用这个公用的函数代码。如图8.5所示。

    图8.5

    显然,这样做会大大节约存储空间。C++编译系统正是这样做的,因此每个对象所占用的存储空间只是该对象的数据部分所占用的存储空间,而不包括函数代码所占用的存储空间。如果声明了一个类:

    复制代码
    class Time
    {
      public:
      int hour;
      int minute;
      int sec;
      void set( )
      {
          cin>>a>>b>>c;
      }
    };
    复制代码

    可以用下面的语句来输出该类对象所占用的字节数:

      cout<<sizeof(Time)<<endl;

    输出的值是12。

    这就证明了一个对象所占的空间大小只取决于该对象中数据成员所占的空间,而与成员函数无关。

    函数代码是存储在对象空间之外的。如果对同一个类定义了10个对象,这些对象的成员函数对应的是同一个函数代码段,而不是10个不同的函数代码段。需要注意的是: 虽然调用不同对象的成员函数时都是执行同一段函数代码,但是执行结果一般是不相同的。

    不同的对象使用的是同一个函数代码段,它怎么能够分别对不同对象中的数据进行操作呢?
    原来C++为此专门设立了一个名为this的指针,用来指向不同的对象。需要说明:
    不论成员函数在类内定义还是在类外定义,成员函数的代码段都用同一种方式存储。
    不要将成员函数的这种存储方式和inline(内置)函数的概念混淆。
    应当说明: 常说的“某某对象的成员函数”,是从逻辑的角度而言的,而成员函数的存储方式,是从物理的角度而言的,二者是不矛盾的。

    4、对成员函数的自我理解

    以上是转载文章的博主对成员函数的理解,但依旧还是没有解决疑惑,就像上面代码类的大小是12字节,int为4字节,3个int形变量正好12个字节。

    1、所以成员函数在这个类中是不占用字节的,2、在文章解说多个调用类对象调用成员函数时指向一个成员函数地址;

    这两点很重要这两点解释了面向对象语言类的本质情况,学过c语言的同学对结构体应该很了解了,是一种自定义的数据类型,对比结构体和类会发现两者非常相似,当然结构体还是太简陋了,结构体内部不能级联相关的函数;但是你细想结构体内部有3个int变量,答应这个结构体的sizeof大小也是12;这样就很有意思了,why为什么会这样,我类中还有成员函数,为什么和你结构体大小一样呢?

    我的理解是类中成员就像面向过程c语言中定义在主函数外部的函数没什么区别,不同的是成员函数可以放在类里面并且可以通过类对象直接使用,而c语言中的函数不能放在结构体内部,这是因为编译器的不同规则的不同所导致的,比如说定义一个man的类其中有一个name函数,xiaoming是man类的对象,xiaoming这个对象在使用name时可以用xiaoming.name来使用,xiaoming这个类对象下的成员变量所占据内存得和是类的内存大小,成员函数就像其他函数一样分布在内存的某个地方,所以不需要将成员函数所占内存算加到类中(如果算到的话就像图8.4所示,这样太浪费内存),以内存层面来说成员函数算不上是类里面的东西,但在书写层面来看成员函数就是类中的东西,造成这种情况的原因是c++编译器与c编译器的不同,C++编译器知道成员函数在编译时候分布在哪里并且根据规则它知道这个函数是哪个类下的函数,在这个类对象以xiaoming.name形式(这种形式也是在c++这种编译器下的一种规则)来调用函数name时编译器编译时知道在这个时候pc(程序计数器)应该指到name函数存放的内存处了,就像c语言调用外部函数编译时编译到mian函数中调用外部函数将pc值指向外部函数的内存一样道理。

    c++编译器这个小秘书,在编译时会做很多自动的处理,比如说自动调用无参构造、析构、在引用前加*号等等(引用是一个常指针),所以在一些理解时会造成困扰

  • 相关阅读:
    Python3学习笔记22-文件读写
    Python3学习笔记21-实例属性和类属性
    Python3学习笔记20-获取对象信息
    Python3学习笔记19-继承和多态
    Python3学习笔记18-访问限制
    Python3学习笔记17-类与实例
    Python3学习笔记16-错误和异常
    Python3学习笔记15-迭代器与生成器
    Python3学习笔记14-迭代与列表生成式
    Python3学习笔记13-函数的参数
  • 原文地址:https://www.cnblogs.com/zhj868/p/14272545.html
Copyright © 2020-2023  润新知