C++中的对象初始化
1 class MyCppClass 2 { 3 }
一旦我们为一个类编写了default constructor,那么编译器也就不会为其默认生成default constructor,对于其他几个函数也一样。对于编译器默认生成的constructor来说,它会以一定规则对每一个数据成员进行初始化。考虑到成员初始化的重要性,在编写自己的constructor时就需要严谨认真了,特别是在类的派生与继承情况下这点显得尤为重要。对于copy constructor和assignment operator的运用场景,这里不得不多说一点,见如下代码:
1 #include <iostream> 2 3 using std::cout; 4 using std::endl; 5 6 class MyCppClass 7 { 8 public: 9 MyCppClass() 10 { 11 std::cout <<"In Default Constructor!" <<std::endl; 12 } 13 14 MyCppClass(const MyCppClass& rhs) 15 { 16 std::cout <<"In Copy Constructor!" <<std::endl; 17 } 18 19 MyCppClass& operator= (const MyCppClass& rhs) 20 { 21 std::cout <<"In Copy Assignment Operator!" <<std::endl; 22 23 return *this; 24 } 25 }; 26 27 int main() 28 { 29 MyCppClass testClass1; // default constructor 30 MyCppClass testClass2(testClass1); // copy constructor 31 testClass1 = testClass2; // copy assignment operator 32 33 MyCppClass testClass3 = testClass1; // copy constructor 34 35 return 0; 36 }
执行结果:
1 // 数据成员类型为内置类型 2 class MyCppClass 3 { 4 public: 5 // 赋值操作进行成员初始化 6 MyCppClass 7 { 8 counter = 0; 9 } 10 11 // 初始化列表进行成员初始化 12 MyCppClass : counter(0) 13 { 14 } 15 16 private: 17 int counter; 18 }
1 // 数据成员类型为自定义类型:一个类 2 class MyCppClass 3 { 4 public: 5 // 赋值操作进行成员初始化 6 MyCppClass(string name) 7 { 8 counter = 0; 9 theName = name; 10 } 11 12 // 初始化列表进行成员初始化 13 MyCppClass : counter(0), theName(name) 14 { 15 } 16 17 private: 18 int counter; 19 string theName; 20 }
1 2 #include <iostream> 3 #include <string> 4 5 class SubClass 6 { 7 public: 8 SubClass() 9 { 10 std::cout <<" In SubClass Default Constructor!" <<std::endl; 11 } 12 13 SubClass(const SubClass& rhs) 14 { 15 std::cout <<" In SubClass Copy Constructor!" <<std::endl; 16 } 17 18 SubClass& operator= (const SubClass& rhs) 19 { 20 std::cout <<" In SubClass Copy Assignment Operator!" <<std::endl; 21 22 return *this; 23 } 24 }; 25 26 class BaseClass 27 { 28 public: 29 BaseClass(const SubClass &rhs) 30 { 31 counter = 0; 32 theBrother = rhs; 33 std::cout <<" In BaseClass Default Constructor!" <<std::endl; 34 } 35 36 BaseClass(const SubClass &rhs, int cnt):theBrother(rhs),counter(cnt) 37 { 38 std::cout <<" In BaseClass Default Constructor!" <<std::endl; 39 } 40 41 BaseClass(const BaseClass& rhs) 42 { 43 std::cout <<" In BaseClass Copy Constructor!" <<std::endl; 44 } 45 46 BaseClass& operator= (const BaseClass& rhs) 47 { 48 std::cout <<" In BaseClass Copy Assignment Operator!" <<std::endl; 49 50 return *this; 51 } 52 private: 53 int counter; 54 SubClass theBrother; 55 }; 56 57 int main() 58 { 59 SubClass subClass; 60 61 std::cout <<"\nNo Member Initialization List: " <<std::endl; 62 BaseClass BaseClass1(SubClass); 63 64 std::cout <<"\nMember Initialization List: " <<std::endl; 65 BaseClass BaseClass2(SubClass, 1); 66 67 return 0; 68 }
执行结果:
为了更好的理解它们,先对C++当中的数据类型进行简单划分。在C++里面,数据类型大致可以分为两种:第一种是内置类型,比如float, int, double等;第二种是自定义类型,也就是我们常用的class, struct定义的类。在对这些类型的数据进行初始化时,差别就体现出来了:对于内置类型,在使用之前必须进行显示的初始化,而对于自定义类型,初始化责任则落在了构造函数身上。
1 int x = 0; // 显示初始化x 2 SubClass subClass; // 依赖SubClass的default constructor进行初始化
上面的名词“缺省初始化”描述的就是当内置类型或者自定义类型的数据没有进行显示初始化时的一种初始化状态,而“隐式初始化”描述的是在该状态下面进行的具体操作方式,比如对于内置类型来说,缺省初始化状态下进行的隐式初始化实际上是未定义的,而自定义类型的隐式初始化则依赖于其constructor。
- 对象被用来初始化一个容器元素
- 为映射表添加一个新元素,对象是这个添加动作的副作用
- 定义一个特定长度的容器,对象为容器的元素
1 #include <iostream> 2 #include <vector> 3 #include <map> 4 #include <string> 5 6 using std::cout; 7 using std::endl; 8 using std::vector; 9 using std::map; 10 using std::string; 11 12 class NumbericInitTestClass 13 { 14 public: 15 void PrintCounter() 16 { 17 cout <<"counter = " <<counter <<endl; 18 } 19 private: 20 int counter; 21 }; 22 23 24 int main() 25 { 26 NumbericInitTestClass tnc; 27 tnc.PrintCounter(); 28 29 map<string, int> mapTest; 30 cout <<mapTest["me"] <<endl; 31 32 vector<NumbericInitTestClass> vecNumbericTestClass(1); 33 vecNumbericTestClass[0].PrintCounter(); 34 35 return 0; 36 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。