亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

解鎖即可觀看《物聯網/嵌入式工程師》完整課程視頻

物聯網/嵌入式工程師

重磅升級:新增硬件電路設計與實戰,讓你軟硬通吃,同級PK無敵!行業風口、政策傾斜,新晉熱門高薪不內卷!0基礎一站式就業完整路徑,搶占先發優勢!

【第1周】邁進供不應求的物聯網/嵌入式行業大門
【第2周】C語言進階-編程思想
【第3周】C語言高級進階
【第4周】C語言項目實戰與《階段筆試》
【第5周】數據結構-線性結構、非線性結構等
【第6周】排序與復雜度&數據結構項目實戰
【第7周】Shell編程和Makefile工程管理
【第8周】Linux文件IO和標準IO
【第9周】Linux下文件操作項目實踐與階段評測
【第10周】Linux 多進程、多線程、IO模型
【第11周】Linux 項目實戰-實現并發服務器模型與企業筆試
【第12周】網絡基礎和UDP Socket編程
【第13周】TCP Socket編程和WireShark抓包分析
【第14周】網絡編程項目實戰-網絡視頻監控與企業筆試
【第15周】從C到C++
【第16周】軟件設計模式與C++11新特性
【第17周】項目實戰-C++語言實現五子棋游戲與企業筆試
【第18周】嵌入式產品人機交互必備-QT框架
【第19周】項目實戰-QT開發音樂播放器
【第20周】智能硬件開發-ARM核介紹和基礎外設
【第21周】智能硬件開發-單片機常用外設
【第22周】stm32芯片-智能硬件項目實戰與企業筆試
【第23周】大廠必備- linux內核與文件系統移植
【第24周】嵌入式開發-系統移植-bootloader、yocto
【第25周】嵌入式底層核心技能-Linux設備驅動初級
【第26周】嵌入式底層核心技能-Linux設備驅動中級
【第27周】嵌入式底層核心技能-Linux設備驅動高級1
【第28周】嵌入式底層核心技能-Linux設備驅動高級2
【第29周】智能家居項目實戰之Linux智能網關端開發
【第30周】智能家居項目實戰之STM32單片機設備端開發
【第31周】人臉指紋識別考勤機設計與實戰
【第32周】硬件電路設計-電路基礎知識
【第33周】STM32最小系統 - 硬件電路設計實戰項目(一)
【第34周】CAN總線分析儀 - 硬件電路設計實戰項目(二)
【第35周】4路輸入輸出控制器 - 硬件電路設計實戰項目(三)
【第36周】8路邏輯分析儀 - 硬件電路設計實戰項目(四)
【第37周】項目答辯和就業指導&獨立開發階段-三大熱門領域項目
章節
問答
課簽
筆記
評論
占位
占位

復制一個員工:賦值構造函數

上一小節中,我們介紹了構造函數和析構函數。這一小節,我們來介紹一個特殊的構造函數。

先來看一個例程:

int main(int argc,char **argv)
{
    Staff staffA;
    Staff staffB = staffA;

    return 0;
}

我們先實例化了一個對象 staffA,然后又實例化了一個對象 staffB。希望 staffB 和 staffA 具有相同的內容,或者說希望 staffB 是 staffA 的副本,那么我們一般直接在實例化的時候進行賦值就可以了。

Staff staffB = staffA;

這樣做了之后,C++ 會自動為我們拷貝 staffA 中的成員變量到 staffB 的成員變量中,但是這種自動拷貝機制在某些情況下無法完成我們想要的動作,甚至有可能會出錯。我們來具體看一下。

在 Staff 類中添加一些內容:

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("構造函數被調用\n");
}

Staff::~Staff()
{
    if(mem != nullptr){
        free(mem);
        mem = nullptr;
    }
    printf("析構函數被調用\n");
}

在上面的代碼中,在類中定義了一個指針,在構造函數中,通過 malloc 函數分配了一個 20 字節大小的堆內存,然后將這片堆內存的首地址賦值給了這個指針。在析構函數中,我們將這片堆內存釋放掉。

這個時候,我們再進行一開始的操作:

Staff staffB = staffA;

先來看看 staffA 在實例化之后的內存布局:

mem 指針指向了一片 20 個字節大小的堆內存。

這個時候,再來看看執行了Staff staffB = staffA;之后,staffB 的內存布局會怎么樣:

可以看到,在 C++ 默認的復制模式之下,兩個對象中的 mem 指針指向了同一片內存。因為 C++ 默認的復制模式只會簡單得把成員的值進行復制,面對這個 mem 指針,他只會把指針的值進行拷貝,最后的結果就是 mem 指針指向了同一片內存。

這種拷貝方式,被稱之為淺拷貝。

賦值構造函數

Staff staffB = staffA;

當我們使用這種方式實例化對象的時候,并不會調用普通構造函數,而是會調用一個特殊的構造函數,被稱之為賦值構造函數或者拷貝構造函數。如果我們沒有寫,那么就會按照淺拷貝的方式來進行復制。一個拷貝構造函數看起來就像下面這樣:

Staff(const Staff & staff);

這個函數中只有一個參數 staff,表示要拷貝的對象,在我們的例子中,就是 staffA。(const 和 & 我們在后續的課程中會具體講解)

那么我們來完整的編寫一下這個函數

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("構造函數被調用\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("析構函數被調用\n");
}

任務

?不會了怎么辦
||

提問題

寫筆記

公開筆記
提交
||

請驗證,完成請求

由于請求次數過多,請先驗證,完成再次請求

加群二維碼

打開微信掃碼自動綁定

您還未綁定服務號

綁定后可得到

  • · 粉絲專屬優惠福利
  • · 大咖直播交流干貨
  • · 課程更新,問題答復提醒
  • · 賬號支付安全提醒

收藏課程后,能更快找到我哦~

使用 Ctrl+D 可將課程添加到書簽

邀請您關注公眾號
關注后,及時獲悉本課程動態

舉報

0/150
提交
取消
全部 精華 我要發布
全部 我要發布
最熱 最新
只看我的

手記推薦

更多

本次提問將花費2個積分

你的積分不足,無法發表

為什么扣積分?

本次提問將花費2個積分

繼續發表請點擊 "確定"

為什么扣積分?