C++ 拷贝构造函数和重载赋值运算符的区别
文章目錄
- 拷貝構(gòu)造函數(shù)
- 重載賦值運(yùn)算符
賦值運(yùn)算符和拷貝構(gòu)造函數(shù)最大區(qū)別是賦值運(yùn)算符沒有新的對(duì)象生成,而拷貝構(gòu)造函數(shù)會(huì)生成新的對(duì)象。
為了更加形象 準(zhǔn)確得描述 賦值運(yùn)算符和拷貝構(gòu)造函數(shù)得區(qū)別,將詳細(xì)通過代碼展示兩者之間得差異。
拷貝構(gòu)造函數(shù)
首先從構(gòu)造函數(shù)說起,在C++面向?qū)ο蟮脑O(shè)計(jì)中,每一個(gè)對(duì)象代表一個(gè)抽象集合的實(shí)體,此時(shí)每一個(gè)實(shí)體在當(dāng)前運(yùn)行的進(jìn)程中是需要對(duì)應(yīng)的內(nèi)存空間,即對(duì)象存在則有空間。為此,C++引入構(gòu)造函數(shù)來實(shí)例化對(duì)象,并讓編譯器為該對(duì)象向操作系統(tǒng)申請(qǐng)對(duì)應(yīng)的空間,從而能夠存在于操作系統(tǒng)之中。
拷貝構(gòu)造函數(shù)則是為了將老對(duì)象的數(shù)據(jù)成員一一賦值給新的對(duì)象數(shù)據(jù)成員的一種構(gòu)造函數(shù),即拷貝構(gòu)造函數(shù)的結(jié)果和構(gòu)造函數(shù)一致,都是有新的對(duì)象生成。
查看如下代碼:
#include <iostream>
using namespace std;class A{
public:A(){ cout << "default constructor " << endl; }A(int a) {num=a;cout << "constructor with param" << endl; }A(const A &a){num=a.num;cout << "copy constructor " << endl;}~A(){ cout << "destructor " << this->num << endl; }void print(){cout << this->num << endl;}private:int num;};
void para_copy(A &a)
{
}
int main()
{A a(100); // 重載構(gòu)造函數(shù)A a1=a; //拷貝構(gòu)造函數(shù)a1.print();A c;//默認(rèn)構(gòu)造函數(shù)return 0;
}
輸出如下:
constructor with param //a 重載構(gòu)造
copy constructor //a1 拷貝構(gòu)造
100
default constructor //c默認(rèn)構(gòu)造
destructor 0 //c析構(gòu)
destructor 100 //a1析構(gòu)
destructor 100 //a析構(gòu)
拷貝構(gòu)造函數(shù)調(diào)用場(chǎng)景如下:
- 我們?nèi)缟洗a中 一個(gè)對(duì)象由另一個(gè)對(duì)象來初始化
- 對(duì)象作為函數(shù)參數(shù)
- 對(duì)象作為函數(shù)返回值
關(guān)于對(duì)象作為函數(shù)參數(shù)以及返回值時(shí)調(diào)用的拷貝構(gòu)造函數(shù),查看代碼如下
輸出如下#include <iostream> using namespace std;class A{ public:A(){ cout << "default constructor " << endl; }A(int a) {num=a;cout << "constructor with param" << endl; }A(const A &a){num=a.num;cout << "copy constructor " << endl;}~A(){ cout << "destructor " << this->num << endl; }void print(){cout << this->num << endl;}private:int num;}; void param_copy(A a) {cout << "param obj" << endl; } A return_value() {A d(0);cout << "return obj" << endl;return d; } int main() {A c;param_copy(c);return_value();return 0; }default constructor //c 默認(rèn)構(gòu)造 copy constructor // 對(duì)象做參數(shù),拷貝構(gòu)造到臨時(shí)對(duì)象 param obj destructor 0 // 析構(gòu)掉臨時(shí)對(duì)象 constructor with param //函數(shù)return_value中 d 對(duì)象使用了重載構(gòu)造函數(shù) return obj destructor 0 //析構(gòu)掉 d對(duì)象 ,局部變量 destructor 0 //析構(gòu)掉 c對(duì)象
關(guān)于深拷貝和淺拷貝的描述如下:
-
通常,默認(rèn)生成的拷貝構(gòu)造函數(shù)和賦值運(yùn)算符,只是簡(jiǎn)單的進(jìn)行值的復(fù)制。如果類的數(shù)據(jù)成員有指針,僅僅通過值傳遞進(jìn)行拷貝構(gòu)造的話會(huì)造成兩個(gè)對(duì)象的成員指針指向同一塊內(nèi)存,當(dāng)兩個(gè)對(duì)象析構(gòu)的時(shí)候會(huì)對(duì)同一個(gè)內(nèi)存釋放兩次,從而會(huì)造成指針空懸。
-
深拷貝即以上第二種情況,數(shù)據(jù)成員中有指針變量的時(shí)候拷貝構(gòu)造函數(shù)使用深拷貝,即構(gòu)造函數(shù)中重新指定初始化對(duì)象的地址空間。
代碼如下:
#include <iostream> using namespace std;class A{ public:A(){ p=new int(10);cout << "default constructor " << endl; }//A(int a) {num=a;cout << "constructor with param" << endl; }A(const A &a){num=a.num;p=new int(10);*p=*(a.p);cout << "copy constructor " << endl;}~A(){ cout << "destructor " << this->num << endl; }void print(){if(p!=NULL){delete p;cout << this->num << endl;}}private:int num;int *p;}; void param_copy(A a) {cout << "param obj" << endl; } int main() {A c;A b(c);return 0; }
重載賦值運(yùn)算符
賦值運(yùn)算符和拷貝構(gòu)造函數(shù)最大區(qū)別即是賦值運(yùn)算符沒有新的對(duì)象生成,而拷貝構(gòu)造函數(shù)會(huì)生成新的對(duì)象。
#include <iostream>
using namespace std;class Person
{
public:Person(){}Person(const Person& p){cout << "Copy Constructor" << endl;}Person& operator=(const Person& p){cout << "Assign" << endl;return *this;}private:int age;string name;
};void f(Person p)
{return;
}Person f1()
{Person p;return p;
}int main()
{Person p;Person p1 = p; // Acout <<" p1 addr " << &p1 << endl;Person p2;cout <<" p2 addr " << &p2 << endl;p2 = p; // Bcout <<" p2 addr after asign " << &p2 << endl;f(p2); // C f函數(shù)參數(shù)cout <<" p2 addr after asign " << &p2 << endl;p2 = f1(); // D f1返回值為改對(duì)象,則先進(jìn)行拷貝構(gòu)造,在將返回的對(duì)象賦值給p2cout <<" p2 addr after asign " << &p2 << endl;Person p3 = f1(); // E 生成新對(duì)象,則為拷貝構(gòu)造函數(shù)cout <<" p3 addr " << &p3 << endl;getchar();return 0;
}
輸出如下:
Copy Constructor
Assign
Copy Constructor
Copy Constructor
Assign
Copy Constructor
總結(jié)
以上是生活随笔為你收集整理的C++ 拷贝构造函数和重载赋值运算符的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个生病简短的个性签名!
- 下一篇: 关于部署osd过程中:Device is