物聯(lián)網(wǎng)/嵌入式工程師
重磅升級:新增硬件電路設(shè)計與實戰(zhàn),讓你軟硬通吃,同級PK無敵!行業(yè)風口、政策傾斜,新晉熱門高薪不內(nèi)卷!0基礎(chǔ)一站式就業(yè)完整路徑,搶占先發(fā)優(yōu)勢!
上一小節(jié)中,我們介紹了構(gòu)造函數(shù)和析構(gòu)函數(shù)。這一小節(jié),我們來介紹一個特殊的構(gòu)造函數(shù)。
先來看一個例程:
int main(int argc,char **argv) { Staff staffA; Staff staffB = staffA; return 0; }
我們先實例化了一個對象 staffA,然后又實例化了一個對象 staffB。希望 staffB 和 staffA 具有相同的內(nèi)容,或者說希望 staffB 是 staffA 的副本,那么我們一般直接在實例化的時候進行賦值就可以了。
Staff staffB = staffA;
這樣做了之后,C++ 會自動為我們拷貝 staffA 中的成員變量到 staffB 的成員變量中,但是這種自動拷貝機制在某些情況下無法完成我們想要的動作,甚至有可能會出錯。我們來具體看一下。
在 Staff 類中添加一些內(nèi)容:
Staff.hpp
#include <string> class Staff { public: Staff(std::string _name, int _age); ~Staff(); public: std::string name; int age; char * mem = nullptr; };
Staff.cpp
#include "Staff.hpp" #include <stdio.h> Staff::Staff(std::string _name, int _age) { mem = (char *)malloc(20); name = _name; age = _age; printf("構(gòu)造函數(shù)被調(diào)用\n"); } Staff::~Staff() { if(mem != nullptr){ free(mem); mem = nullptr; } printf("析構(gòu)函數(shù)被調(diào)用\n"); }
在上面的代碼中,在類中定義了一個指針,在構(gòu)造函數(shù)中,通過 malloc 函數(shù)分配了一個 20 字節(jié)大小的堆內(nèi)存,然后將這片堆內(nèi)存的首地址賦值給了這個指針。在析構(gòu)函數(shù)中,我們將這片堆內(nèi)存釋放掉。
這個時候,我們再進行一開始的操作:
Staff staffB = staffA;
先來看看 staffA 在實例化之后的內(nèi)存布局:
mem 指針指向了一片 20 個字節(jié)大小的堆內(nèi)存。
這個時候,再來看看執(zhí)行了Staff staffB = staffA;
之后,staffB 的內(nèi)存布局會怎么樣:
可以看到,在 C++ 默認的復(fù)制模式之下,兩個對象中的 mem 指針指向了同一片內(nèi)存。因為 C++ 默認的復(fù)制模式只會簡單得把成員的值進行復(fù)制,面對這個 mem 指針,他只會把指針的值進行拷貝,最后的結(jié)果就是 mem 指針指向了同一片內(nèi)存。
這種拷貝方式,被稱之為淺拷貝。
Staff staffB = staffA;
當我們使用這種方式實例化對象的時候,并不會調(diào)用普通構(gòu)造函數(shù),而是會調(diào)用一個特殊的構(gòu)造函數(shù),被稱之為賦值構(gòu)造函數(shù)或者拷貝構(gòu)造函數(shù)。如果我們沒有寫,那么就會按照淺拷貝的方式來進行復(fù)制。一個拷貝構(gòu)造函數(shù)看起來就像下面這樣:
Staff(const Staff & staff);
這個函數(shù)中只有一個參數(shù) staff,表示要拷貝的對象,在我們的例子中,就是 staffA。(const 和 & 我們在后續(xù)的課程中會具體講解)
那么我們來完整的編寫一下這個函數(shù)
Staff.hpp
#include <string> class Staff { public: Staff(std::string _name, int _age); Staff(const Staff & staff); ~Staff(); public: std::string name; int age; char * mem = nullptr; };
Staff.cpp
#include "Staff.hpp" #include <stdio.h> Staff::Staff(std::string _name, int _age) { mem = (char *)malloc(20); name = _name; age = _age; printf("構(gòu)造函數(shù)被調(diào)用\n"); } Staff::Staff(const Staff & staff) { name = staff.name; age = staff.age; mem = (char *)malloc(20); memcpy(mem, staff.mem, 20); } Staff::~Staff() { if(mem != nullptr){ free(mem); mem = nullptr; } printf("析構(gòu)函數(shù)被調(diào)用\n"); }
請驗證,完成請求
由于請求次數(shù)過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報