溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C++拷貝構(gòu)造函數(shù)中的陷阱怎么解決

發(fā)布時(shí)間:2022-01-06 14:32:28 來源:億速云 閱讀:134 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“C++拷貝構(gòu)造函數(shù)中的陷阱怎么解決”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“C++拷貝構(gòu)造函數(shù)中的陷阱怎么解決”吧!

拷貝構(gòu)造函數(shù)大家都比較熟悉,通俗講就是傳入一個(gè)對(duì)象,拷貝一份副本。
不過看似簡(jiǎn)單的東西,實(shí)際不注意的話就會(huì)產(chǎn)生問題!

#include<iostream>
using namespace std;
class CExample
{
public:
int a,b,c;
char *str;
public:
//構(gòu)造函數(shù)
    CExample(int tb)
    {
        a = tb;
        b = tb+1;
        c = tb+2;
        str=(char *)malloc(sizeof(char)*10);
strcpy(str,"123456789");
cout<<"creat: "<<endl;
    }
 
//析構(gòu)函數(shù)
    ~CExample()
    {
cout<< "delete: "<<endl;
    }
void Show ()
{
cout<<a<<endl;
    }
//拷貝構(gòu)造
//CExample(const CExample& C)
//{
//    str=(char *)malloc(sizeof(char)*10);
//    strcpy(str,C.str);
//    cout<<"copy"<<endl;
//}
};
//全局函數(shù),傳入的是對(duì)象
void g_Fun(CExample C)
{
    C.a=0;C.b=0;C.b=0;
strcpy(C.str,"aaabbbccc");
cout<<"test"<<endl;
}
int main()
{
CExample test(1);
cout<<"str:"<<test.str<<" a="<<test.a<<" b="<<test.b<<" c="<<test.c<<endl;
    g_Fun(test);//傳入對(duì)象
cout<<"str:"<<test.str<<" a="<<test.a<<" b="<<test.b<<" c="<<test.c<<endl;
    getchar();
return 0;
}

這個(gè)結(jié)果似乎出乎了我們的預(yù)料,作為形式參數(shù) test對(duì)象被修改了,同時(shí)是test.str的部分被修改了,test的整數(shù)成員變量沒有被修改!

咱們先了解一下系統(tǒng)默認(rèn)的拷貝構(gòu)造函數(shù),因?yàn)轭愔袥]有寫自己的拷貝構(gòu)造函數(shù),所以調(diào)用的是默認(rèn)的拷貝構(gòu)造函數(shù)。

Thinking in c++:對(duì)于簡(jiǎn)單結(jié)構(gòu),編譯器會(huì)自動(dòng)生成一個(gè)缺省的,就是位拷貝(bitcopy)。

對(duì)于比較復(fù)雜的類型,編譯器就會(huì)自動(dòng)生成一個(gè)缺省的拷貝構(gòu)造函數(shù)。

class CExample
{
int a,b,c;
};

這就是一個(gè)簡(jiǎn)單結(jié)構(gòu)的類,位拷貝,就是按對(duì)象在內(nèi)存中的二進(jìn)制進(jìn)行拷貝,對(duì)于不涉及指針等類型的時(shí)候,位拷貝是比較不錯(cuò)的拷貝方法。

但是,要是一個(gè)類中有指針類型的時(shí)候,如:

class CExample
{
int a,b,c;
char *str;
};

位拷貝就會(huì)把指針地址拷貝了一下,話句話說,這里只進(jìn)行了“淺拷貝”,一旦副本里涉及到指針的操作,必然就會(huì)影響到原始對(duì)象的成員變量,這就是導(dǎo)致,上面代碼中對(duì)象的整數(shù)變量沒被修改(對(duì)整數(shù)變量的位拷貝其實(shí)就是一種“深拷貝”),而str所指的對(duì)象被修改的原因。

那么該如何防止對(duì)副本的修改影響原始對(duì)象呢?

答案是用戶自定義拷貝構(gòu)造函數(shù)!

CExample(const CExample& C)
{
    a=C.a;b=C.b;c=C.b;
    str=(char *)malloc(sizeof(char)*10);
strcpy(str,C.str);
cout<<"copy"<<endl;
}

這樣就可以正確完成拷貝構(gòu)造的操作了。

總結(jié):對(duì)于簡(jiǎn)單的數(shù)據(jù)類型,可以使用系統(tǒng)默認(rèn)的拷貝構(gòu)造函數(shù);但對(duì)于復(fù)雜的數(shù)據(jù)類型(如指針),其實(shí)就是深拷貝和淺拷貝的區(qū)別!一般類如果包含指針或引用成員,應(yīng)該遵守Rule of Three原則。

@24K純開源 指出的三法則:
三法則(英語:rule of three,the Law of The Big Three,The Big Three;三法則,三大定律)在 C++ 程序設(shè)計(jì)里,它是一個(gè)以設(shè)計(jì)的基本原則而制定的定律,三法則的要求在于,假如類型有明顯地定義下列其中一個(gè)成員函數(shù),那么程序員必須連其他二個(gè)成員函數(shù)也一同編寫至類型內(nèi),亦即下列三個(gè)成員函數(shù)缺一不可。

析構(gòu)函數(shù)(Destructor

復(fù)制構(gòu)造函數(shù)(copy constructor

復(fù)制賦值運(yùn)算符(copy assignment operator

感謝各位的閱讀,以上就是“C++拷貝構(gòu)造函數(shù)中的陷阱怎么解決”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)C++拷貝構(gòu)造函數(shù)中的陷阱怎么解決這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI