C++:构造函数2——拷贝构造函数
前言:拷貝構造函數是C++中的重點之一,在這里對其知識進行一個簡單的總結。
一、什么是拷貝構造函數
在C++中,對于內置類型的變量來說,在其創建的過程中用同類型的另一個變量來初始化它是完全可以的,如:
1 int value=100; 2 int new_value=value;//在變量new_value創建的同時用同類型的變量value來初始化它那么對于自定義的數據類型來說,是否可以在該類的一個對象創建時用該類的另一個對象對其進行初始化呢?看下例:
1 #include<iostream>2 #include<string>3 using namespace std;4 class Student{5 public:6 Student()=default;//默認構造函數7 Student(string name,int age):Name(name),Age(age){} //構造函數 8 ~Student(){}//析構函數9 void message();//打印對象的信息 10 private: 11 string Name; 12 int Age; 13 }; 14 15 void Student::message(){ 16 cout<<"My name is "<<Name<<endl; 17 cout<<"I am "<<Age<<" years old"<<endl; 18 } 19 int main(){ 20 Student stu1("Tomwenxing",23); 21 Student stu2(stu1); 22 stu2.message(); 23 return 0; 24 }由上面的例子可以看出可以用一個類的對象去對該類的另一個正在創建的新對象進行初始化。而完成這個工作的就是類中的拷貝構造函數。所謂拷貝構造函數是一種特殊的構造函數,它由編譯器調用來完成一些基于同一類的其他對象的構建及初始化。如果編程者在編寫自定義的類時沒有自定義拷貝構造函數,那么編譯器會在類中定義一個默認的拷貝構造函數。
語法:類名(const 類名 &對象名) { /*拷貝構造函數體*/} 1 #include<iostream>2 #include<string>3 using namespace std;4 class Student{5 public:6 Student()=default;//默認構造函數7 Student(string name,int age):Name(name),Age(age){} //構造函數 8 Student(const Student& stu){ //拷貝構造函數 9 Name=stu.Name; 10 Age=stu.Age; 11 cout<<"調用了拷貝構造函數!"<<endl; 12 } 13 ~Student(){}//析構函數 14 void message();//打印對象的信息 15 private: 16 string Name; 17 int Age; 18 }; 19 20 void Student::message(){ 21 cout<<"My name is "<<Name<<endl; 22 cout<<"I am "<<Age<<" years old"<<endl; 23 } 24 int main(){ 25 Student stu1("Tomwenxing",23); 26 Student stu2(stu1); 27 stu2.message(); 28 return 0; 29 }特別注意:
拷貝構造函數的函數名必須和類名相同,且其唯一的參數(對象的引用)是不可變的(const類型)
?
二、拷貝構造函數的調用
在C++中,有三種情況會使對象在創建時調用拷貝構造函數
case 1:對象以值傳遞的方式傳入函數參數
當對象直接作為參數以值傳遞的方式傳遞給函數時,函數將調用類中的拷貝構造函數并將實參對象傳遞給該拷貝構造函數從而在內存中創建形參對象,該形參對象將在函數執行完畢后調用類的析構函數將其析構
1 #include<iostream>2 #include<string>3 using namespace std;4 class Student{5 public:6 Student(){//默認構造函數7 cout<<"調用了默認構造函數 "<<this<<endl; 8 }9 Student(string name,int age):Name(name),Age(age){//構造函數1 10 cout<<"調用了構造函數1 "<<this<<endl; 11 } 12 Student(const Student& stu){ 13 Name=stu.Name; 14 Age=stu.Age; 15 cout<<"調用了拷貝構造函數!"<<this<<endl; 16 } 17 ~Student(){//析構函數 18 cout<<"調用了析構函數 "<<this<<endl; 19 } 20 void message();//打印對象的信息 21 private: 22 string Name; 23 int Age; 24 }; 25 26 void Student::message(){ 27 cout<<"My name is "<<Name<<endl; 28 cout<<"I am "<<Age<<" years old"<<endl; 29 } 30 31 void func1(Student s){ 32 cout<<"調用了函數func1"<<endl; 33 cout<<"形參變量的地址為"<<&s<<endl; 34 } 35 int main(){ 36 Student stu("Tomwenxing",23); 37 cout<<"實參變量的地址為"<<&stu<<endl; 38 cout<<"準備調用函數func1"<<endl; 39 func1(stu); 40 cout<<"函數func1調研完畢"<<endl; 41 return 0; 42 }case 2:對象以值傳遞的方式從函數返回
當對象以值傳遞的方式從函數返回時,函數會調用類中的拷貝構造函數并將要返回的對象傳遞給該拷貝構造函數從而在內存中創建一個臨時對象,該臨時對象會在返回后(不管有沒有對象接收(拷貝)該臨時對象)立馬調用類中的析構函數進行析構。
1 #include<iostream>2 #include<string>3 using namespace std;4 class Student {5 public:6 Student() {//默認構造函數7 cout << "調用了默認構造函數 " << this << endl; 8 }9 Student(string name, int age) :Name(name), Age(age) {//構造函數1 10 cout << "調用了構造函數1 " << this << endl; 11 } 12 Student(const Student& stu) { 13 Name = stu.Name; 14 Age = stu.Age; 15 cout << "調用了拷貝構造函數!" << this << endl; 16 } 17 ~Student() {//析構函數 18 cout << "調用了析構函數 " << this << endl; 19 } 20 void message();//打印對象的信息 21 private: 22 string Name; 23 int Age; 24 }; 25 26 void Student::message() { 27 cout << "My name is " << Name << endl; 28 cout << "I am " << Age << " years old" << endl; 29 } 30 31 Student func1() { 32 cout << "調用了函數func1" << endl; 33 Student s("Tomwenxing", 23); 34 cout << "函數中的局部對象s在內存中的地址:" << &s << endl; 35 return s;36 } 37 int main() { 38 cout << "準備調用函數func1" << endl; 39 func1(); 40 cout << "函數func1調研完畢" << endl; 41 return 0; 42 }case 3:對象在創建過程中被相同類型的其他對象初始化
當對象在創建過程中被同類型的其他對象進行初始化時,該對象會調用類中的拷貝構造函數并將對其初始化的對象作為實參傳遞給該類的拷貝構造函數,從而最終將本對象成功創建
1 #include<iostream>2 #include<string>3 using namespace std;4 class Student{5 public:6 Student(){//默認構造函數7 cout<<"調用了默認構造函數 "<<this<<endl; 8 }9 Student(string name,int age):Name(name),Age(age){//構造函數1 10 cout<<"調用了構造函數1 "<<this<<endl; 11 } 12 Student(const Student& stu){ 13 Name=stu.Name; 14 Age=stu.Age; 15 cout<<"調用了拷貝構造函數!"<<this<<endl; 16 } 17 ~Student(){//析構函數 18 cout<<"調用了析構函數 "<<this<<endl; 19 } 20 void message();//打印對象的信息 21 private: 22 string Name; 23 int Age; 24 }; 25 26 void Student::message(){ 27 cout<<"My name is "<<Name<<endl; 28 cout<<"I am "<<Age<<" years old"<<endl; 29 } 30 31 int main(){ 32 Student stu1("Tomwenxing",23); 33 Student stu2(stu1);//初始化形式一 34 Student stu3=stu1;//初始化形式二 35 return 0; 36 }?
總結
以上是生活随笔為你收集整理的C++:构造函数2——拷贝构造函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++:类中的赋值函数
- 下一篇: C/C++ 类默认生成的四个函数