c++对象模型
在c++的对象中,其对象模型是从简单对象模型派生而来的,并对内存空间和存取时间做了优化,在此模型中,
1.非静态数据成员放在class内
如果有个全局变量和其同名,一般不会造成冲突,其编译器会暗中给数据进行独一无二的识别代码(不仅是数据成员,还有class函数也是)
如:
static x;
class Obj
{
public:
...
private:
int x;
}
比如Obj的数据成员x可能会被命名为@Obj1_x,而全局静态成员会被命名为@global_x;
2.静态数据成员则被存放在class外
其被视为一个global变量(但只在class生命范围内可见),每一个member的存取许可,以及与class的关联,并不会导致任何空间上或执行时间上的额外负担-----不论是在个别的class objects 或是在static data member,每一个static data member 只有一个实体,存放在数据段。
3.如果有虚函数,则class object 被安插一个指针,指向相关的virtual table。通常这个指针被称为vptr,其虚表中都是那些虚函数
4.如果存在继承,那么就会加入继承的这个对象的数据布局(先不说虚继承)
上面这样的c++对象模型,让c++和c的struct有着很好的兼容性,你并不能说其class和struct有什么不一样(从数据布局来说),所以我觉得这样可以更好的兼容c和c++;
比如:
struct Obj
{
int x;
int y;
void print()
{
printf("x: %d\ny: %d\n",x,y);
}
};
class Obj
{
public:
Obj(int x,int y):_x(x),_y(y){};
~Obj();
void print()
{
cout<<"x: "<<_x<<endl;
cout<<"y: "<<_y<<endl;
}
private:
int _x;
int _y;
};
其struct和这个class并没有区别;当出现继承的时候,其实就是多了几个虚指针而已;
但是通过这个虚指针,c++就可以实现面向对象模型;
Default Constructor
有以下4中情况编译器会未声明constructor的classes合成一个default construct:
- “带有Default Constructor”的Member Class Object
- "带有Default Constructor"的Base Class
- “带有一个Virtual Function”的class
- “带有一个Virtual Base Class”的class
Copy Constructor
Default Memberwise Initialization or Bitwise Copy Semantics
当相同的class object相互copy时,会发生Default Memberwise Initialization or Bitwise Copy Semantics,
当发生以下4中情况的话,就不会发生Bitwise Copy Semantics:
- 当class 内含一个member object 而后者的class声明有一个copy constructor 时
- 当class继承自一个base class 而后者存在一个copy constructor时
- 当class声明了一个或多个virtual functions时
- 当class派生自一个继承串链,其中有一个或多个virtual base classes时
当不相同的有继承关系的class相互赋值时可能会发生重新设定virtual table 指针: