当前位置:首页 > 编程教程 > c++编程 > 笔记):构造函数之初始化列表

笔记):构造函数之初始化列表

2017-10-10 09:07:38[c++编程]点击数:作者:未知 来源: 网络
随机为您推荐的文章:杭电ACM第1004题Let the Balloon Rise

#include <stdio.h> #include<string.h> #include <stdlib.h> int main(){         int n,i,j,k,max,flag;                 while(scanf("%d",&n)&&n!=0){                 char **p=(char **)malloc(n*sizeo

在这里将为大家介绍的是 笔记):构造函数之初始化列表的相关介绍,具体代码请看下文

一、为了更好的说明初始化列表,首先由一个错误的代码引入:

1 #include<iostream> 2 3 #include"string.h" 4 using namespace std; 5 6 class Student 7 { 8 private: 9 int Num,Chinese,Maths,English; 10 float Total; 11 char Name[20]; 12 public: 13 Student(){}//默认构造函数 14 Student(char name[20],int num,int chinese,int maths,int english); 15 16 }; 17 Student::Student(char name[20],int num,int chinese,int maths,int english){ 18 int n; 19 for(n=0;n<strlen(name);n++) 20 Name[n]=name[n]; 21 Num=num; 22 Chinese=chinese; 23 English=english; 24 Maths=maths; 25 Total=maths+chinese+english; 26 } 27 28 int main() 29 { 30 int i,j; 31 int num,chinese,maths,english; 32 char name[20]; 33 Student std[5];//因为有了默认构造函数所以此时编译可以通过 34 35 for(i=0;i<5;i++) 36 { 37 cin>>name[20]>>num>>chinese>>maths>>english; 38 std[i](name[20],num,chinese,maths,english); 39 for(j=0;j<20;j++) 40 name[j]='\0'; 41 42 } 43 } View Code

上面代码在编译的时候出现一个错误提示:
[Error] no match for call to '(Student) (char&, int&, int&, int&, int&)'
该错误定位到下面这行std[i](name[20],num,chinese,maths,english);该段代码错误的原因是误认为先定义一个Student 的数组,之后调用构造函数来进行赋值,实际上,构造函数是在Student std[5];这句定义的时候就调用默认构造函数初始化了 (如果读者不明白构造函数的执行过程请参考我的上篇笔记)。所有构造函数(可以是默认构造或者非平凡构造)都是在定义的时候就调用,定义以后的调用就不叫初始化了,而是赋值。写这个错误代码的人,明显是没有理解构造函数是怎么执行的,
他的目的是通过循环依次调用构造函数来进行初始化。当然我们可以按照他的想法来进行"正确"的编写代码,将上面的错误行出修改为std[i].Student(name[20],num,chinese,maths,english);

这样看起来才像是对象本身来调用构造函数进行初始化。遗憾的是,这样也是无法编译的,出现下面的错误信息:
[Error] invalid use of 'Student::Student'

出现这样的错误是因为,C++本身就要求在定义的时候系统自动调用构造函数,而对象是不能调用构造函数的。

解决方案:

1、可以在定义的时候直接初始化,为了方便的说明问题,我们把上面的Student std[5];这句代码中改为1个数组元素,for循环去掉,
就变成下面的代码了(这段代码仅仅c++11支持):

1 #include<iostream> 2 3 #include"string.h" 4 using namespace std; 5 6 class Student 7 { 8 private: 9 int Num,Chinese,Maths,English; 10 float Total; 11 char Name[20]; 12 public: 13 Student(){}//默认构造函数 14 Student(char name[20],int num,int chinese,int maths,int english); 15 16 }; 17 Student::Student(char name[20],int num,int chinese,int maths,int english){ 18 int n; 19 for(n=0;n<strlen(name);n++) 20 Name[n]=name[n]; 21 Num=num; 22 Chinese=chinese; 23 English=english; 24 Maths=maths; 25 Total=maths+chinese+english; 26 } 27 28 int main() 29 { 30 int i,j; 31 int num,chinese,maths,english; 32 char name[20]; 33 Student std[1] = { { name,num,chinese,maths,english} }; 34 35 36 } View Code

2、还可以定义一系列指针,然后再每次构造的时候调用new来构造类对象。
如:

1 Student *std[5];
2 for(i=0;i<5;i++)
3 {
4 cin>>name[20]>>num>>chinese>>maths>>english;
5 std[i]=new Student(name,num,chinese,maths,english);
6 */ 

为了更好的看到new对象的时候,构造函数是怎么执行的,简单的更改一下上面的代码如下:

1 #include<iostream> 2 3 #include"string.h" 4 using namespace std; 5 6 class Student 7 { 8 private: 9 int Num,Chinese,Maths,English ; 10 float Total; 11 public: 12 Student(){}//默认构造函数 13 Student( int num ); 14 15 }; 16 Student::Student(int num ){ 17 18 cout<<"第" << num <<"个构造函数" <<endl; 19 Num = num; 20 cout<<"Num = "<<num<<endl; 21 } 22 23 int main() 24 { 25 int i; 26 int num,chinese,maths,english; 27 28 Student *std[5]; 29 for(i=0;i<5;i++) 30 { 31 std[i]=new Student( i );//每申请一块内存就自动调用构造函数 32 } 33 } View Code

结果如图所示:

 笔记):构造函数之初始化列表 1 class Student 2 { 3 private: 4 int m_num,m_maths ; 5 public: 6 Student(){}//默认构造函数 7 Student(int num,int maths ):m_num(num),m_maths(maths) 8 { 9 10 cout<<"进入计算阶段" <<endl; 11 cout<<"m_num = "<<num<<endl; 12 } 13 14 };

为了更好的了解初始化列表,首先我们要知道,构造函数的执行可以分成两个阶段,初始化阶段和计算阶段,初始化阶段先于计算阶段。而初始化阶段就是对应着初始化列表那部分,而计算阶段就是构造函数的函数体部分。初始化阶段先于计算阶段执行,如下面程序:

 1 #include<iostream>
 2  
 3 #include"string.h"
 4 using namespace std;
 5 
 6 class Student
 7 {
 8     private:
 9     int m_num,m_maths ;
10     public:
11         Student(){}//默认构造函数 
12          Student(int num,int maths );
13 };
14 Student::Student(int num,int maths  ):m_num(num),m_maths(maths)
15 {
16     cout<<"进入计算阶段前m_num = "<<m_num <<endl; 
17     this->m_num = 2;
18     cout<<"进入计算阶段后查看m_um = "<<m_num<<endl;
19 }
20  
21 int main()
22 {
23     
24     Student A(1,2); 
25 }

试验结果图如下:

1 #include<iostream> 2 3 using namespace std; 4 5 class Student1 { 6 public: 7 int a; 8 9 Student1() // 无参构造函数 10 { 11 cout << "默认构造函数Student1" << endl ; 12 } 13 14 Student1(const Student1& t1) // 拷贝构造函数 15 { 16 cout << "拷贝构造函数Student1" << endl ; 17 this->a = t1.a ; 18 } 19 20 Student1& operator = (const Student1& t1) // 赋值运算符 21 { 22 cout << "赋值函数Student1" << endl ; 23 this->a = t1.a ; 24 return *this; 25 } 26 }; 27 class Student2 28 { 29 public: 30 31 Student1 test ; 32 Student2(Student1 &t1){ //图1结果 33 test = t1 ; 34 } 35 }; 36 int main() 37 { 38 39 Student1 A; 40 Student2 B(A); 41 42 } View Code

代码2:

1 #include<iostream> 2 3 using namespace std; 4 5 class Student1 { 6 public: 7 int a; 8 9 Student1() // 无参构造函数 10 { 11 cout << "默认构造函数Student1" << endl ; 12 } 13 14 Student1(const Student1& t1) // 拷贝构造函数 15 { 16 cout << "拷贝构造函数Student1" << endl ; 17 this->a = t1.a ; 18 } 19 20 Student1& operator = (const Student1& t1) // 赋值运算符 21 { 22 cout << "赋值函数Student1" << endl ; 23 this->a = t1.a ; 24 return *this; 25 } 26 }; 27 class Student2 28 { 29 public: 30 31 Student1 test ; 32 Student2(Student1 &t1):test(t1){} 33 }; 34 int main() 35 { 36 37 Student1 A; 38 Student2 B(A); 39 40 } View Code

代码1图:

 笔记):构造函数之初始化列表

从图中可以看出第一段代码的计算结果调用了2次构造函数和1次赋值函数,而代码2结果,调用了1次构造函数和1次拷贝函数。
当代码量比较多的时候会发现,代码2比代码1效率更高。

谢谢您的访问.

这些内容可能对你也有帮助

更多c++编程可查看c++编程列表页。

TAGS: 初始化   函数   笔记   列表