Storage allocation
◆ The compiler allocates all the storage for a scope at the opening brace of that scope.
◆ The constructor call doesn't happen until the sequence point where the object is defined.
Example:
#include <iostream> using namespace std; class A { public: A(); ~A(); void print(); }; A::A() { printf("inside A Constructor\n"); } A::~A() { printf("inside A Destructor\n"); } void A::print() { printf("this = %p\n", this); } int main(int argc, const char* argv[]) { A a; printf("&a = %p\n", &a); A aa; printf("&aa = %p\n", &aa); return 0; }从下面的运行结果,可以看到,分配空间是在进入main()的大括号{}的时候就已经给对象a和aa分配了空间,但是对象a和aa的构造函数的调用是在之后才进行的:
【例】
#include <iostream> using namespace std; class X { private: int x; }; void f(int i); int main(int argc, const char* argv[]) { int i; scanf("%d", &i); f(i); return 0; } void f(int i) { if (i < 10) { goto jump; } X x1; //Constructor called here jump: switch (i) { case 1: X x2; //Constructor called here break; case 2: X x3; //Constructor called here break; } }这种if-else/case语句,会使得跳过对象x1、x2和x3的构造函数,导致编译失败
Aggregate initialization
int a[5] = { 1, 2, 3, 4, 5 }; int b[6] = { 5 }; int c[] = { 1, 2, 3, 4 }; // - sizeof(c) / sizeof(*c); struct X { int i, float f; char c; }; // - X x1 = { 1, 2.2, 'c' }; X x2[3] = { {1, 1.1, 'a'}, {2, 2.2, 'b'} }; struct Y { float f; int i; Y(int a) }; Y y1[] = { Y(1), Y(2), Y(3) }; //对于对象,我们要调用构造函数才能生成对象The default constructor
◆ A default constructor is one that can be called with no arguments.
struct Y { float f; int i; Y(int a); //有参数的构造函数,不是default constructor } Y y1[] = { Y(1), Y(2), Y(3) }; Y y2[2] = { Y(1) }; //错误【例】
#include <iostream> using namespace std; class X { private: int i; public: X(int a); }; X::X(int a) { i = a; } int main(int argc, const char* argv[]) { X x(1); X x1[2] = { X(1) }; return 0; }此时编译器会报错:“X”: 没有合适的默认构造函数可用,因为在x1[1]对象初始化时,没有调用X::X(int a);这样编译器会默认以为需要一个默认的构造函数X::X();来初始化这个对象x1[1],然而编译器去查找却找不到这样的函数,就会报错