3 c++ compiler-construction constructor
在这样的C代码中:
{
int i = 5;
/* ....... */
}
Run Code Online (Sandbox Code Playgroud)
编译器将通过向下移动堆栈指针(对于堆栈向下)移动int的大小来替换代码,并将值5放在该内存位置.
同样,在C++代码中,如果创建了一个对象,编译器会做什么?例如:
class b
{
public :
int p;
virtual void fun();
};
main()
{
b obj;
}
Run Code Online (Sandbox Code Playgroud)
编译器会为上面的代码做些什么?任何人都可以解释何时分配内存,何时分配虚拟表的内存,以及何时调用默认构造函数?
从逻辑上讲,两者之间没有区别:
在这两种情况下,堆栈都足够大以容纳对象,并且在对象上调用构造函数.
请注意:
你可以这样思考:
int x; // stack frame increased by sizeof(int) default construct (do nothing)
B a; // stack frame increased by sizeof(B) default construct.
Run Code Online (Sandbox Code Playgroud)
而:
int y(6); // stack frame increased by sizeof(int) Copy constructor called
B b(a); // stack frame increased by sizeof(B) Copy constructor called
Run Code Online (Sandbox Code Playgroud)
好.当然,POD类型的构造函数非常简单,编译器会进行大量优化(并且可能除了删除任何实际代码甚至内存地址),但从逻辑上讲,将它想象成这样的方式就好了.
注意:所有类型都有一个复制构造函数(如果不这样,编译器会定义一个)和POD类型,你可以在逻辑上把它看作是复制构造而没有任何问题.
首先请注意,这是一个实现细节,并非所有编译器都使用它们.
但是vtable本身通常是在编译时生成的.任何需要vtable的对象都有一个不可见的指针添加到结构中(这是作为对象大小的一部分包含的).然后在构造期间,指针被设置为指向vtable.
注意:定义何时设置vtable是不可能的,因为标准没有定义,因此每个编译器可以随时自由地执行.如果你有一个多级层次结构,那么vtable可能是由每个构造函数从基数到大多数派生的,因此可能是错误的,直到最终的构造函数完成.
注意:您无法在构造函数/析构函数中调用虚函数.所以你可以说只有在构造函数完全完成后才能正确初始化vtable.