C++底层设计--对象(成员布局、多态实现)
C语言中,数据和处理数据的操作是分开声明的,语言本身没有支持“数据和函数”的关联。
C++中支持封装,在软件工程层面上看,比在C语言中使用全局数据好。
C++支持封装性质,在不使用虚函数或抽象类时,不会带来额外的开销(空间、效率)。
C++对象模型中,non-static成员数据放在每个对象中,而static成员数据放在所有对象外。且static和non-static成员函数放在所有对象之外。
虚标的支持:每个对象有一个指针,指向virtual table(vtbl),虚表每项指向每个虚函数。
在虚拟继承中,基类不管在继承链中被派生多少次,永远只有一个实体。如iostream中只有virtual ios base class的实体。
在C++中,struct可以替代class,也可声明public、protected、private等区段,使用虚函数,以及单一和多重继承,虚拟继承等。不过class与struct区别在于:struct默认的访问属性为public,而class默认访问属性为private。
C++中处于同一个区段的数据,保证在内存布局与声明次序相同。而放置在多个区段的数据,排列次序就不定了。同样,基类和派生类的成员数据布局前后顺序也没有强制规定。
对于C++中,class使用C风格的struct,可使用组合(composition)的方式,class中内含一个C struct的对象。这保证了struct中变量内存布局次序与与struct声明次序相同。
C++直接支持三种编程模型:
①程序模型,如C语言一样。
②抽象数据类型模型,ADT,抽象数据类型并提供一个public接口。
③面向对象模型,OO,存在多个彼此联系类型,由基类继承而来。
C++中,只有通过pointer和reference间接处理,才能支持OO程序设计得多态性质。
C++中,内置类型不能实现多态。
C++中,一个类对象内存大小表现在non-static成员数据、对齐空间以及支持virtual所需额外空间。
各个指针指向的地址并无区别,指针的类型决定在该地址存取的字节数。所以,void *指针包含一个地址,而不能通过它来操作对象。
class Bear : public ZooAnimal {
public:
Bear();
~Bear();
//...
void rotate();
virtual void dance();
//...
protected:
enum Dances{ ... };
dances dances_known;
int cell_block;
};
Bear b("Yogi");
Bear *pb = &b;
Bear &rb = *pb;
它的内存分布为:
对于Bear指针和一个ZooAnimal指针没有不同,但两个存取内存大小不同。
对于pz指针,它指向一Bear对象,但使用pz->cell_block却是不合法的,因为pz为基类指针,不能访问派生类的成员。可以使用类型转换:
当一个基类对象被直接初始化为一个派生类对象时,派生类对象将被切割赋值给基类。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/m0_38076911/article/details/96900570