#include <iostream> #include <vector> #include <string> using namespace std; int global_n; // 函数体外的内置类型变量被自动初始化为0 // // 系统将提供一个默认构造函数来构造ClassA对象 class ClassA { public: void output() { cout << "ClassA" << endl; } }; // // 默认构造函数并没有初始化数据成员m_Value, 这将使此成员处于未定义状态!! // 带一个int参数的构造函数使得系统不提供默认构造函数, ClassB对象无法被默认构造!! class ClassB { public: ClassB(int v) { m_Value = v; } void output() { cout << "ClassB, Value: " << m_Value << endl; } private: int m_Value; }; // // 含有ClassB类型的数据成员的类, 由于ClassB没有默认构造函数, // ClassUseB对象也无法被默认构造!! class ClassUseB { public: void output() { cout << "In ClassUseB - "; m_Value.output(); } private: ClassB m_Value; }; // // ClassC提供了默认构造函数, 并使用初始化列表正确地初始化了数据成员 class ClassC { public: ClassC() : m_Value(0) {} void output() { cout << "ClassC, Value: " << m_Value << endl; } private: int m_Value; }; // 由于ClassC有默认构造函数, 所以以它为数据成员的类可以被默认构造 class ClassUseC { public: void output() { cout << "In ClassUseC - "; m_Value.output(); } private: ClassC m_Value; }; // // 使用构造函数初始化列表初始化2个数据成员, 注意顺序和定义顺序不一致 class ClassD { public: ClassD() : m_B(2), m_A(1) {} void output() { cout << "ClassD, Value: " << m_A << ", " << m_B << endl; } private: int m_A; int m_B; }; // // 初始化列表中, m_A根据m_B的值来初始化自己, 这将导致错误或未定义行为, // 初始化顺序应该和数据成员定义的顺序一致 class ClassE { public: ClassE() : m_B(1), m_A(m_B*2) {} // m_A将初始化失败! 其值不确定 //ClassE() : m_A(m_B*2), m_B(1) {} // 同上 //ClassE() : m_A(1), m_B(m_A*2) {} // 成功初始化2者 void output() { cout << "ClassE, Value: " << m_A << ", " << m_B << endl; } private: int m_A; int m_B; }; // // const类型或引用类型的数据成员, 以及没有默认构造函数的类类型的成员, // 必须在构造函数初始化列表中进行初始化 class ClassF { public: // 失败 //ClassF() //{ // m_Const = 1; // m_Ref = 2; // m_B(3); //} ClassF() : m_Const(1), m_temp(2), m_Ref(m_temp), m_B(3) {} void output() { cout << "ClassF, m_Const: " << m_Const << ", m_Ref: " << m_Ref << ", "; m_B.output(); } private: const int m_Const; int m_temp; // 为m_Ref提供变量引用 int& m_Ref; ClassB m_B; }; // // 使用默认实参的构造函数 class ClassG { public: ClassG(int v = 1) : m_Value(v) {} void output() { cout << "ClassG, Value: " << m_Value << endl; } private: int m_Value; }; // // 隐式类类型的转换 // 可以用单个实参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换 class ClassH { public: ClassH() : m_Str("null"), m_Int(0) {} ClassH(string& s) : m_Str(s), m_Int(1) {} ClassH(int i) : m_Str("null"), m_Int(i) {} void output() { cout << "ClassH, m_Str: " << m_Str << ", m_Int: " << m_Int << endl; } private: string m_Str; int m_Int; }; // // 使用explict, 抑制隐式类类型的转换 // 要进行类型转换, 必须显式调用相应构造函数 class ClassI { public: ClassI() : m_Str("null"), m_Int(0) {} explicit ClassI(string& s) : m_Str(s), m_Int(1) {} explicit ClassI(int i) : m_Str("null"), m_Int(i) {} void output() { cout << "ClassI, m_Str: " << m_Str << ", m_Int: " << m_Int << endl; } private: string m_Str; int m_Int; }; int main() { // 函数体内的内置类型变量不自动初始化, 拷贝初始化 int n1 = 10; // 函数体内的内置类型变量不自动初始化, 直接初始化 int n2(10); // n3没有被初始化, 对n3的使用将导致未定义行为 // VC++2005: Run-Time Check Failure #3 - The variable 'n3' is being used without being defined. int n3; // 使用不含参数的, 明确的构造函数调用语法, 内置类型变量会被初始化为0 int n4 = int(); cout << "global_n: " << global_n << ", n1: " << n1 << ", n2: " << n2 // << ", n3: " << n3 << << ", n4: " << n4 << endl; cout << endl; ClassA a; a.output(); cout << endl; // 以下操作均将失败, 因为ClassB没有默认构造函数! //ClassB b; //b.output(); //ClassUseB ub; //ub.output(); //ClassB arrB[3]; //arrB[0].output(); //vector<ClassB> vecB; //vecB.push_back(b); //vecB[0].output(); // 必须用构造函数构造ClassB对象 ClassB b2(2); b2.output(); cout << endl; // 以下构造正确, 因为ClassC可以被默认构造 ClassC c; c.output(); ClassUseC uc; uc.output(); ClassC arrC[3]; arrC[0].output(); vector<ClassC> vecC; vecC.push_back(c); vecC[0].output(); cout << endl; // ClassD, ClassE, ClassF演示构造函数初始化列表的使用及注意事项 ClassD d; d.output(); ClassE e; e.output(); ClassF f; f.output(); cout << endl; // 使用默认实参的构造函数 ClassG g; g.output(); cout << endl; // 隐式类类型转换 ClassH h1; string str = "test"; ClassH h2 = str; ClassH h3 = 3; h1.output(); h2.output(); h3.output(); cout << endl; // 使用explicit关键词, 限制构造函数进行隐式转换 ClassI i1; //ClassI i2 = str; // ERROR, 已限制隐式转换 //ClassI i3 = 3; // ERROR, 已限制了隐式转换 ClassI i4(str); // OK, 显式转换 ClassI i5(3); // OK, 显式转换 i1.output(); i4.output(); i5.output(); cout << endl; cout << endl; system("PAUSE"); }