精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C++之拷貝構造函數的淺copy及深copy

電子設計 ? 來源:電子設計 ? 作者:電子設計 ? 2020-12-24 15:31 ? 次閱讀

一、深拷貝和淺拷貝構造函數總結:

1、兩個特殊的構造函數:

(1)無參構造函數:

沒有參數的構造函數

Class Test

public
Test()

//這是一個無參構造函數

};

當類中沒有定義構造函數時,編譯器默認提供一個無參構造函數,并且其函數體為空;換句話來說,就是我們在類中,不用我們程序猿自己寫,編譯就自動提供了無參構造函數(只是我們肉眼看不到!)

#include <iostream>
#include <string>
class Test{
//編譯器默認給我們提供了一個無參構造函數,只是我們肉眼看不到
};
int main()

Test t;
return 0;

結果輸出(編譯時能夠通過的):

root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp#

(2)拷貝構造函數:

參數為const class_name&的構造函數

class Test{
public:
Test(const Test& p)




當類中沒有定義拷貝構造函數時,編譯器默認提供了一個拷貝構造函數,簡單的進行成員變量的值賦值

#include <iostream>
#include <string>
class Test{
private:
int i;
int j;
public:
Test(const Test& p)編譯器默認提供這樣操作的

i = p.i;
j = p.j;

};
int main()

Test t;
return 0;

輸出結果(編譯可以通過):

root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp#

(3)注意:

在寫程序的時候,定義的類對象初始化時看屬于哪種類型的:

Test t;//對應無參構造函數
Test t(1);//對應有參構造函數
Test t1;
Test t2=t1;//對應拷貝構造函數

比如下面我定義的類對象屬于無參構造函數(當然前提是你手寫了其他構造函數,雖然說編譯器會默認提供,但是既然要手寫,那么三種構造函數就在定義類對象的時候按需求來寫),如果只寫了有參數構造函數,那么編譯器就會報錯:

#include <iostream>
#include <string>
class Test{
private:
int i;
int j;
public:
Test(int a)

i = 9;
j=8;

Test(const Test& p)

i = p.i;
j = p.j;

};
int main()

Test t;
return 0;

輸出結果:

root@txp-virtual-machine:/home/txp# g++ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:25:9: error: no matching function for call to ‘Test::Test()’
Test t;

test.cpp:25:9: note: candidates are:
test.cpp:15:3: note: Test::Test(const Test&)
Test(const Test& p)

test.cpp:15:3: note: candidate expects 1 argument, 0 provided
test.cpp:10:3: note: Test::Test(int)
Test(int a)

test.cpp:10:3: note: candidate expects 1 argument, 0 provided

4、拷貝構造函數的意義:

(1)淺拷貝

拷貝后對象的物理狀態相同

(2)深拷貝

拷貝后對象的邏輯狀態相同

(3)編譯器提供的拷貝構造函數只進行淺拷貝

代碼版本一:

#include <stdio.h>
#include <string>
class Test{
private:
int i;
int j;
int *p;
public:
int getI()

return i;

int getJ()

return j;

int *getP()

return p;

Test(int a)

i = 2;
j = 3;
p = new int;
*p = a;

void free()

delete p;

};
int main()

Test t1(3);//Test t1 3;
Test t2 = t1;
printf("t1.i = %d, t1.j = %d, t1.p = %p", t1.getI(), t1.getJ(), t1.getP());
printf("t2.i = %d, t2.j = %d, t2.p = %p", t2.getI(), t2.getJ(), t2.getP());
t1.free();
t2.free();

return 0;

輸出結果:

root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp# ./a.out
t1.i = 2, t1.j = 3, t1.p = 0x1528010
t2.i = 2, t2.j = 3, t2.p = 0x1528010
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001528010 ***
Aborted (core dumped)

注解:出現了段錯誤,仔細分析,我們發現這里釋放了堆空間兩次(因為我們這里沒有調用拷貝構造函數,也就是自己去寫拷貝構造函數;所以這種情況是淺拷貝,不能釋放兩次堆空間):

代碼版本二(加上拷貝構造函數):

#include <stdio.h>
#include <string>
class Test{
private:
int i;
int j;
int *p;
public:
int getI()

return i;

int getJ()

return j;

int *getP()

return p;

Test(int a)

i = 2;
j = 3;
p = new int;
*p = a;

Test(const Test& t)

i = t.i;
j = t.j;
p = new int;
*p = *t.p;

void free()

delete p;

};
int main()

Test t1(4);
Test t2 = t1;
printf("t1.i = %d, t1.j = %d, t1.p = %p", t1.getI(), t1.getJ(), t1.getP());
printf("t2.i = %d, t2.j = %d, t2.p = %p", t2.getI(), t2.getJ(), t2.getP());
t1.free();
t2.free();
return 0;

輸出結果:

root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp# ./a.out
t1.i = 2, t1.j = 3, t1.p = 0xb0a010
t2.i = 2, t2.j = 3, t2.p = 0xb0a030

注解:從打印的p地址空間來看,就知釋放的兩個對象的堆空間不同,不再是指向同一堆空間了;同時我們發現淺拷貝只是簡單數值上的進行賦值而已;深拷貝不只是簡單的值賦值,而是從內存的角度來看,是操作不同的內存。

5、什么時候需要進行深拷貝?

(1)對象中有成員指代了系統中的資源

成員指向了動態內存空間

成員打開了外存中的文件

成員使用了系統中的網絡端口

注意:一般來說,自定義拷貝構造函數(也就是我們自己手寫的),必然需要實現深拷貝!

二、總結:

C++編譯器會默認提供構造函數

無參構造函數用于定義對象的默認初始化狀態

拷貝構造函數在創建對象時拷貝對象的狀態

對象的拷貝有淺拷貝和深拷貝兩種方式。

好了,今天的分享就到這里,如果文章中有錯誤或者不理解的地方,可以交流互動,一起進步。我是txp,下期見!

審核編輯:符乾江
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 可編程邏輯
    +關注

    關注

    7

    文章

    514

    瀏覽量

    44072
  • C++
    C++
    +關注

    關注

    22

    文章

    2104

    瀏覽量

    73489
收藏 人收藏

    評論

    相關推薦

    LMX2594 RFoutA跟RFoutB是什么關系?B可以配置成A的完全一樣的copy嗎?

    想問下RFoutA跟RFoutB是什么關系?B可以配置成A的完全一樣的copy嗎?第一次看芯片手冊沒看明白
    發表于 11-13 08:26

    如何使用SCP和Rsync遠程拷貝文件

    scp是secure copy的簡寫,用于在Linux下進行遠程拷貝文件的命令,和它類似的命令有cp,不過cp只是在本機進行拷貝不能跨服務器,而且scp傳輸是加密的??赡軙晕⒂绊懸幌滤俣取.斈?/div>
    的頭像 發表于 09-29 15:54 ?352次閱讀

    C++中實現類似instanceof的方法

    函數,可實際上C++中沒有。但是別著急,其實C++中有兩種簡單的方法可以實現類似Java中的instanceof的功能。 在 C++ 中,確定對象的類型是編程中實際需求,使開發人員
    的頭像 發表于 07-18 10:16 ?534次閱讀
    <b class='flag-5'>C++</b>中實現類似instanceof的方法

    copy table中存放的是否為初始值不為0的data段所在PFlash的地址信息?

    1. copy table中存放的是否為初始值不為0的data段所在PFlash的地址信息?(比如:int a = 10; 變量a被存放到了PFlash的0x8030001c處,copy table
    發表于 07-02 07:51

    FX2 CY7C68013A如何在C++環境中使用LoadEEPROM函數?

    我使用的是 FX2 CY7C68013A 芯片。 我知道 CyUSB.NET 庫中有我需要的 LoadEEPROM 函數。 請問如何在 C++ 環境而不是 C#/CLR 環境中使用該
    發表于 05-31 06:59

    瑞芯微開發板copy 安卓圖像識別軟件copy

    瑞芯微開發板copy,內置安卓圖像識別軟件,需要copy整個板、系統、識別軟件,歡迎有經驗的同行洽談
    發表于 05-29 18:38

    為什么NAND FLASH沒有COPY back函數?

    為什么我的NAND FLASH 沒有COPY back函數
    發表于 05-10 07:21

    TC212 Flash copy to RAM區出現異常的原因?

    TC212 刷boot然后刷應用程第一次上電flash copy to RAM 正常.(對應flash區數據變化,但對應的RAM區未變化)第二次刷應用程序,flash copy to RAM(ram區保存第一次刷的數據)每次刷完程序都是從新上電
    發表于 02-19 06:58

    TC397不使能SWAP功能的情況下,對UCB_SWAP_ORIG/_COPY操作會鎖芯片嗎?

    我想測試一下對UCB_SWAP_ORIG/_COPY的寫入/擦除操作,請問在不使能SWAP的情況下,對芯片的這種操作是否會鎖片。
    發表于 02-05 08:04

    lsl文件中將text段copy到ram,編譯器具體是如何實現的?

    lsl文件中,將text段copy到ram,編譯器具體是如何實現的?
    發表于 02-02 07:23

    如何知道UCB COPY扇區的確認狀態?

    ”,UCB COPY 扇區仍設置為 “未讀”。 SSW 是否只更新 ORIG 扇區的 PROIN 位? 如何知道復制區域處于已確認或已解鎖狀態? 如果狀態為 UNREAD,我應該直接從 0xAF4 的相應的 UCB 扇區位置讀取值,還是應該使用其他寄存器?
    發表于 01-22 07:39

    C++簡史:C++是如何開始的

    MISRA C++:2023,MISRA? C++ 標準的下一個版本,來了!為了幫助您做好準備,我們介紹了 Perforce 首席技術支持工程師 Frank van den Beuken 博士撰寫
    的頭像 發表于 01-11 09:00 ?536次閱讀
    <b class='flag-5'>C++</b>簡史:<b class='flag-5'>C++</b>是如何開始的

    基于C/C++面向對象的方式封裝socket通信類流程簡析

    在掌握了基于 TCP 的套接字通信流程之后,為了方便使用,提高編碼效率,可以對通信操作進行封裝,本著有的原則,先基于 C 語言進行面向過程的函數封裝,然后再基于
    的頭像 發表于 12-26 10:00 ?1742次閱讀

    基于C/C++面向對象的方式封裝socket通信類

    在掌握了基于 TCP 的套接字通信流程之后,為了方便使用,提高編碼效率,可以對通信操作進行封裝,本著有的原則,先基于 C 語言進行面向過程的函數封裝,然后再基于
    的頭像 發表于 12-26 09:57 ?1284次閱讀

    如何進行零拷貝性能測試

    TogetherROS?·Bot零拷貝性能測試 我們使用TogetherROS?·Bot系統內部集成的性能測試工具——performance_test,來評估下開啟零拷貝前后的性能差異,這里我們傳輸
    的頭像 發表于 11-27 16:51 ?408次閱讀
    如何進行零<b class='flag-5'>拷貝</b>性能測試