(一)默认调用的无参构造函数
#include<iostream> #include<string> using namespace std; class StudentID{ int value; public: StudentID(){ static int nextStudentID = 0; value = ++nextStudentID ; cout<<"Assigning student id "<<value<<endl; } }; class Student{ string name; StudentID id; public: Student(string n = "noName"){ cout<<"Constructing student "<<n<<endl; name = n; } }; int main(){ Student s("Randy"); return 0;
运行结果:
从运行结果来看,学生类对象被构造时,一个学号对象也创建了,而且学号类的构造函数
与学生类对象的构造函数题体的执行之前执行。
C++的类机制对于含有对象的类对象的构造定了一些规则,对于上述程序,其内部执行次序
是这样的:
(1)先分配学生类的对象s的空间,调用Student构造函数。
(2)在Student构造函数题尚未执行之时,由于看到类的对象id,转而去调用学号类的无
参构造函数。
(3)执行了学号类构造函数体,再返回到Student构造函数。
(4)执行Student构造函数,完成全部构造工作。
对学号类的调用是默认的,默认调用便是调用无参构造函数。
(二)如果在学生对象创建中,既要初始化名称,又要初始化学号,不要默认调用无参构
造函数。
1 class StudentID{ 2 int value; 3 public: 4 StudentID(int id = 0){ 5 value = id ; 6 cout<<"Assigning student id "<<value<<endl; 7 } 8 }; 9 10 11 class Student{ 12 string name; 13 StudentID id; 14 public: 15 Student(string n = "noName", int ssID = 0){ 16 cout<<"Constructing student "<<n<<endl; 17 name = n; 18 StudentID id(ssID); 19 } 20 }; 21 22 int main(){ 23 Student s("Randy", 58); 24 return 0; 25 }
运行结果:
重新设计构造函数,对s对象进行初始化,但是从运行结果看到,调用的StudentID构造函
数执行体却没有输出58,而是默认的0。说明调用的仍然是无参构造函数。它的执行过程跟
上例一样,在看到StudentID id;语句时,首先调用默认的无参构造函数,输出0。在执行
到StudentID id(ssID);语句时,才调用有参构造函数,输出58。
(三)使用初始化列表初始化
1 class StudentID{ 2 int value; 3 public: 4 StudentID(int id = 0){ 5 value = id ; 6 cout<<"Assigning student id "<<value<<endl; 7 } 8 }; 9 10 11 class Student{ 12 string name; 13 StudentID id; 14 public: 15 Student(string n = "noName", int ssID = 0):id(ssID),name(n){ 16 cout<<"Constructing student "<<n<<endl; 17 } 18 }; 19 20 int main(){ 21 Student s("Randy", 58); 22 Student s("Hello"); 23 return 0; 24 }
运行结果:
使用参数列表的方式初始化对象,就不会调用无参构造函数,而按构造参数列表中说明的参数要求去调用。