关于类,对象以及成员的内存分布,友元关系


关于类,对象和成员的内存分布

介绍

c++ 程序的内存格局分为4个区,全局数据区,代码区,栈区,堆区,全局数据区存放全局变量,静态数据和常量。所有类成员函数和非成员函数代码存在代码区,为运行函数分配的局部变量,函数参数,返回数据,返回地址等存放在栈区,余下的空间都被称为堆区。

对象是类的实例

c++ 程序的内存格局分为4个区,全局数据区,代码区,栈区,堆区,全局数据区存放全局变量,静态数据和常量。所有类成员函数和非成员函数代码存在代码区,为运行函数分配的局部变量,函数参数,返回数据,返回地址等存放在栈区,余下的空间都被称为堆区。

对象的存储大小

  1. 如果有虚函数,则多一个vptr指针
  2. 如果有虚基类,则多一个vbptr指针
  3. 字节对齐
  4. 空类是没有任何数据成员的类,为了标识它的不同对象,编译器往往会给空类对象分配1个字节的内存空间,如果该类是继承自空类的空类,编译器只给它分配1个字节的空间,不是2个,用来避免空间的浪费,继承自空类的非空类,编译器往往会忽略空类的1个字节的空间,只计算非空类自身数据成员所占空间。

成员函数

  • c++函数在编译时会根据命名空间,类,参数等信息进行重新命名,形成新的函数名,这个重命名通过一个叫做名字编码的算法来重命名的。
  • c++类中函数代码是存在对象之外的,如果对同一个类定义了10个对象,那么这些对象对应同一个函数代码,不是10个不同的函数代码段,c++规定,编译成员函数时要额外添加一个参数,把当前对象的指针传递进去,通过指针来访问变量。

总结

编译器通过指针来访问成员变量,指针指向哪个对象就使用哪个对象的数据,编译器通过指针的类型来访问成员函数,指针属于哪个类的类型就使用哪个类的函数。

关于友元关系

  1. 友元破坏了封装和继承
  2. 友元分为三种,1,友元函数 2,友元类3,友元成员函数。
  3. 友元不具有传递性,不具有对称性,且不能被继承。
  4. 友元函数,在类外定义时不需要加 classname::限定符,也不需要加friend关键字
  5. 友元类,友元类可以访问类中所有成员函数,都可以访问类中隐藏信息。friend class 类名
  6. 友元成员函数,和友元函数一样,不过要主要顺序,使用前向声明,class A; class B{} ;class A{ friend B::func()}编译在A类的定义中看到B类的一个方法被声明A类的友元之前,应该先看到B类的声明和方法的声明。