废弃,请参考
关于对象
对象实际需要的内存大小
- nonstatic data members 总和大小
- 由于alignment需求和填补(padding)上去的空间
- 为了支持virtual而由内部产生的任何额外负担
指针类型
通过指针类型教导编译器如何解释某个地址中的内存内容及其大小。
- 指向1000的int 类型的指针,在32位(int是4-bytes)的机器上,涵盖1000-1003的地址空间
- 指向1000的string类型指针,是8-bytes,包括一个4-bytes的字符指针和一个用来表示字符串长度的整数
所以cast
操作是一种编译器指令,它只影响被指出内存的大小和其内容。
C++程序设计模式
构造函数语义学
Constructor
对于一个class,若没有任何 user-declared constructor,那么会有一个default constructor被implicitly声明出来,这个声明通常是trivial(无能的,在STL中会采用直接内存操作的方式初始化)的,但在以下四种情况,是non-trivial的。
- 带有Default Constructor的Member Class Object时,编译器声明的constructor会调用member class object的default constructor。这种情况下,即使有user-declared constructor,编译器也会按照Member Class Object定义的顺序补充调用他们的默认构造函数。
- 带有Default Constructor的Base Class,derived class A需要合成一个constructor来调用父类的constructor,因此也是non-trival的,如此之后再继承该class A的子类,将把合成的A的constructor当作是显示声明的。
- 此外即使A有user-declared的constructor,编译器也会扩充他们的每一个,按照顺序调用父类的default constructor。
- 和第一种情况类似,Member Class Object的default constructor也会被扩充进来
- 带有或者继承virtual function的class,因为需要给对象赋virtual function的地址;
- 带有一个virtual base class的class,因为需要给对象赋virtual class对象的地址。
Copy Constructor
有三种情况,会以一个object的内容作为另一个class object的初值,如下
1 | class X {...}; |
Copy Constructor的逻辑是把每一个内建的或者派生的data member(例如一个指针或者数组)的值,从一个objec拷贝到另一个object中;对于其中的member class object,会采用递归的方式进行memberwise initialization。
若没有显示的Copy Constructor声明,就会有Implicitly Copy Constructor被声明或者定义出来,他们是不是nontrivial的,会根据他们是否具有bitwise copy semiotics来判断。不遵照bitwise copy semiotics的情况
class中member objects中有声明copy constructor的情况(显式声明或者被编译器合成)
class继承自一个base class而后者存在一个copy constructor时
当class 声明了一个或者多个virtual functions时,由于可能会存在类型的在继承树上的变化,所以需要重新设定virtual table的指针
例如
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class ZooAnimal{
public:
ZooAnimal();
virtual ~ZooAnimal();
virtual void animate();
virtual void draw();
}
class Bear : public ZooAnimal{
public:
Bear();
void animate();
void draw();
virtual void dance();
}
Bear beer;
ZooAnimal a = beer; // 会发生切割行为,逐位复制的方式将会造成vptr错误
当class 派生自一个继承串链,其中有一个或多个virtual base classes时