C 多继承时的对象内存模型,c 关于继承的内存问题

1 , c 关于继承的内存问题它先声明了一个子类的指针,然后将子类指针赋值给a,相当于将指针a指向那块区域 , 所以调用a->set()等函数是允许的,也能正确返回结果a这里不是对象,是指针,任何指针都是4字节(32位机),确实基类是4字节,因为有虚指针,子类不但继承了虚表,还有自身的Int变量b , 所以 是8字节
2,在C中多继承的内存结构是怎么样的类中并不是所有东西都存在类的 , 静态变量是类存储的,非虚函数是类存储一个指针,非静态变量是类的实例对象存储的,虚函数是对象存储的 。因此A的对象内存结构:vtpr:虚函数表指针B成员变量C成员变量A成员变量它先声明了一个子类的指针,然后将子类指针赋值给a , 相当于将指针a指向那块区域,所以调用a->set()等函数是允许的,也能正确返回结果a这里不是对象,是指针,任何指针都是4字节(32位机),确实基类是4字节,因为有虚指针,子类不但继承了虚表 , 还有自身的int变量b,所以 是8字节
3,c 关于继承的内存问题数据成员操作這個沒有問題.在 son::set 之中, this 的型是 son*在 MyClass::set 之中, this 的型是 MyClass*一開始時 son *a = new son; 等号右叩男褪?MyClass*, up-cast 交給a.到 a->set() 時, 由於 virtual function 的 dynamic-binding, 是調用 son::set.調用之前做了個隱藏的down-case:this=(son)a; 所以 this 可以取用 son::b dfghhdfds【C 多继承时的对象内存模型,c 关于继承的内存问题】
4,C 继承对象内存分布如果是普通继承,那么就是先存放基类对象,然后存放子类对象 。如果是普通继承中使用了虚函数,那么就是将虚函数分配一个虚表,用来存储虚函数的指针 。当使用父类指针或者引用调用子类对象时 , 可以检索到对应的虚函数 。如果是虚继承,主要是应对类似水晶形态继承的情况,详细的内容可以参考下面提供的资料 。C++继承多态下的内存分布http://blog.163.com/stu_shl/blog/static/59937509201132884721415/C++中多态的实现原理http://www.cnblogs.com/dongzhiquan/archive/2011/10/25/2223251.html水晶形态的继承结构http://pcedu.pconline.com.cn/empolder/gj/c/0503/579115_1.htmla 构造和析构不能被继承,但基类一定要调用 b 对 c 显然是错的 d 继承层次中只要有一次私有继承,就可以剥夺子类对基类公有成员的访问权5,c 关于内存模型的问题这种问题有必要回一下A a=new B();内存分配过程分为4个阶段1.clr在堆里面计算并开辟一段内存空间,将B对象的实例的各个字段的默认值分配到该空间上;2.除此之外外,clr需要为该对象分配额外的2个字节:syncblockindex和指向方法表的指针,分别用于标记该对象的同步状态和虚方法地址 。3.调用B对象的构造函数 。注意构造函数是根据继承树逐级调用的(即object()->A()->B()) 。4.在堆栈上为A引用(指针)开辟一段4字节空间,并使其指向堆中的B对象 。参考《.net框架程序设计》一个类是分成两部分的,一部分存数据一类的东西 , 比如说类里的field,另一部分存逻辑,比如method 。数据的那一部分,是每一个实例有一份,逻辑的部分,每一个类只有一份 。A a = new B();里面,B()的返回值是你真正建立的实例,a只不过是为了你可以在以后描述它而起的名字,这种关系在C\C++里叫pointer,在C#、Java里叫reference,在python里叫name binding , 都是相似的 。所以,在A a=new B()里面实际上是不存在像int32转换成int64那样真正的conversion的,只不过是用A类的名字指向一个B类的实例而已 。允许这样操作的原因是因为B继承A , 所以A的内容是B的子集,A有的东西B一定都有 。b0sus说得不错 , 我也不想多说了 。介绍几本书吧(要学好C#有些书是一定要看的) 。首先是学.net一定要看的《.net框架程序设计》,看完对.net框架尤其是CLR和CTS有比较直观的理解.另外《.net 2.0面向对象编程揭秘》也非常好,个人认为是国内最好的讲.net 2.0的书 。我推荐一本《你必须知道的.net》通俗易懂 , 本人受宜非浅

    推荐阅读