前言:构造函数是C+中很重要的一个概念,这里对其知识进行一个简单的总结
一、构造函数的定义
1.类中的构造函数名与类名必须相同
2.构造函数没有函数的返回类值型说明符
[特别注意]:
a.构造函数的返回值类型不是void,而是没有
b.构造函数虽然没有返回值类型说明符,但构造函数是有返回值的,构造函数的返回值是其所创建的对象
1 class Student{ 2 public: 3 Student(){} //构造函数的函数名与类名必须相同 4 //构造函数没有返回值类型说明符 5 .....//其他操作 6 }
3.在程序运行时,当新的对象被建立时,该对象所属的类的构造函数自动被调用,且在该对象生存期中只调用这一次
4.构造函数可以重载。在类中可以定义多个构造函数,它们由不同的参数列表区分,系统在自动调用时按一般函数重载的规则选一个执行
1 class Student{ 2 public: 3 Student(){}//构造函数1 4 Student(string name);//构造函数2 5 Student(string name,int age);//构造函数3 6 Student(string name,int age,string gender);//构造函数4 7 private: 8 string Name; 9 int Age; 10 string Gender; 11 } 12 13 int main(){ 14 Student stu1;//调用构造函数1 15 Student stu2("Tomwenxing");//调用构造函数2 16 Student stu3("Tomwenxing",23);//调用构造函数3 17 Student stu4("Tomwenxing",23,"male");//调用构造函数4 18 return 0; 19 }
5.构造函数可以在类中定义,也可以在类外定义
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 class Student{ 5 public: 6 Student(){} 7 Student(string name){//类内定义构造函数 8 this->name=name; 9 } 10 Student(string name,int age);//类内声明构造函数,类外定义构造函数 11 private: 12 string name; 13 int age; 14 }; 15 16 Student::Student(string name,int age){ //类外定义构造函数 17 this->name=name; 18 this->age=age; 19 } 20 21 int main(){ 22 Student stu1; 23 Student stu2("Tomwenxing"); 24 Student stu3("Tomwenxing",23); 25 return 0; 26 }
6.如果类定义中没有定义任何一个构造函数,C++编译器会自动给出一个缺省的构造函数(称为默认构造函数):
默认构造函数:类名(){}
但是,只要我们手动定义了一个构造函数,系统就不会再为我们自动生成缺省的默认构造函数了,如果仍希望类中由默认构造函数,需要编程者自己手动定义
[特别注意]:
只要构造函数是无参的或者只要各参数均有缺省转值的,C++编译器都认为是缺省的构造函数,因此缺省的构造函数在类定义中至多只能有一个
1 #include<iostream> 2 using namespace std; 3 class Student{ 4 public: 5 Student(){} //构造函数1 6 Student(int value=0){//构造函数2 7 this->value=value; 8 } 9 Student(int value=0,int value2=0){//构造函数3 10 this->value=value; 11 this->value2=value2; 12 } 13 private: 14 int value; 15 int value2; 16 }; 17 int main(){ 18 Student stu1; //错误:不知道调用哪个构造函数 19 return 0; 20 }
7.构造函数初始化列表:负责为新创建的对象的一个或几个数据成员赋初值。其中构造函数初始值是成员名字的一个列表,每个名字后面紧跟括号括起来的(或者在花括号内的)成员初始值,且不同成员的初始化通过逗号分开。
1 #include<iostream> 2 using namespace std; 3 class Student{ 4 public: 5 Student(){}//手动定义默认构造函数 6 Student(int value1):Value(value1){}//构造函数初始化列表 7 Student(int value1,int value2); 8 private: 9 int Value; 10 int Value2; 11 }; 12 Student::Student(int value1,int value2):Value(value1),Value2(value2){} 13 int main(){ 14 Student stu1(10); 15 Student stu2(10,20); 16 return 0; 17 }
二、构造函数的三个作用
作用1: 创建对象。当类的对象被创建时,编译系统会为该对象分配内存空间,并自动调用构造函数从而创建该对象
作用2:对创建的对象进行初始化。通常构造函数会在对象被创建的同时对该对象中的成员变量进行初始化。
作用3:类型转换
[作用3的理解]:
理解构造函数的作用3之前,首先需要理解C++中数据类型隐式转换的原理。例:
1 double value=12,59; 2 int new_value=value; //new_value的值是12
上例是C++中常见的不同数据类型之间的隐式转换。C++编译器在编译这种隐式转换语句时会将语句改写成如下情况:
1 double value=12.59; 2 int temp=value;//定义一个临时变量,并用变量value的值对其进行初始化 3 int new_value=temp;
也就是说C++编译器会定义一个临时变量并用temp并用double类型的变量value对其进行初始化,然后再在int类型变量new_value创建时用临时变量temp来对其进行初始化,从而完成不同数据类型之间的隐式类型转换。
同理,C++中也可以利用类中的构造函数来完成不同类型数据之间的转换
1 #include<iostream> 2 using namespace std; 3 class Test 4 { 5 public: 6 Test()=default; //在C++11新标准下,可以通过在参数列表后面写上=default来要求编译器生成默认的构造函数(即Test(){}) 7 Test(int d):value(d){ //构造函数1 8 cout<<"调用了构造函数1"<<endl; 9 } 10 Test(double d):value2(d){ //构造函数2 11 cout<<"调用了构造函数2"<<endl; 12 } 13 private: 14 int value; 15 double value2; 16 }; 17 18 int main(){ 19 Test test1,test2; 20 test1=100;//调用构造函数1来进行类型转换 21 test2=12.5;//调用构造函数2来进行类型转换 22 return 0; 23 }
当C++编译器对语句test1=100;进行编译时,会先利用整数类型数字100调用类的构造函数1来创建一个临时的Test类的对象temp,然后在再临时对象temp赋值给对象test1,也就是会将语句test1=100;转换成下列语句:
1 Test temp(100); 2 test1=temp;
C++编译器对语句test2=12.5;的处理同上,会先利用双精度浮点类型数字12.5调用类的构造函数2来创建一个临时的Test类的对象temp,然后再将临时对象temp赋值给对象test2:
1 Test temp(12.5); 2 test2=temp;
如果键类中的构造函数1和构造函数2注释掉,则语句test1=100;和语句test2=12.5;将会报错,因为编译器在类中找不到构造函数来对其进行类型转换