C++類與對象深度解析(一):從引用、內聯函數到構造析構的編程實踐

目錄

一.引用

引用的特征:1.引用必須初始化

2.本質是別名

3.函數參數傳遞

4.常引用

5.函數返回值

6.權限 放大 縮小 平移

引用 vs 指針

二.內聯函數

關鍵點說明

三.宏函數

四.類

什么是類?

簡單的類

五.構造函數與析構函數

1. 構造函數(Constructor)

使用環境:

2. 析構函數(Destructor)

作用

示例

總結

六.this指針

1.?什么是?this?指針?

2. 為什么需要?this?指針?

3.?注意事項

七.拷貝構造函數

一、什么是拷貝構造函數?

二、淺拷貝(Shallow Copy)

什么是淺拷貝?

淺拷貝的問題

三、深拷貝(Deep Copy)

什么是深拷貝?

深拷貝解決方案

四、關鍵總結


一.引用

引用:引用不是新定義一個量而是給已存變量取一個別名,它和它引用的變量共用一塊空間

引用的特征:

1.引用必須初始化

引用必須在聲明時初始化,且不能重新綁定到其他對象。

int x = 10;
int &ref = x;  // 正確:引用必須初始化
// int &ref2;  // 錯誤:未初始化的引用
2.本質是別名

引用是變量的另一個名字,沒有獨立的內存地址,操作引用等價于操作原變量。

int x = 10;
int &ref = x;  // 正確:引用必須初始化
// int &ref2;  // 錯誤:未初始化的引用
3.函數參數傳遞

引用常用于函數參數,避免拷貝開銷且允許修改實參(替代指針的簡潔語法)。

void swap(int &x, int &y) {int temp = x;x = y;y = temp;
}int main() {int a = 1, b = 2;swap(a, b);  // 直接傳遞變量,無需取地址cout << a << " " << b;  // 輸出 2 1
}
4.常引用

常引用可以綁定到臨時對象或字面量,且不能通過引用修改原對象

const int &r1 = 42;  // 正確:常引用可綁定到字面量
int x = 10;
const int &r2 = x;   // 正確:r2 是 x 的只讀別名
// r2 = 20;          // 錯誤:不能通過常引用修改值
5.函數返回值

引用可以作為函數返回值,但需確保返回的對象生命周期有效(避免懸空引用)。

int global = 100;int& getGlobal() {return global;  // 返回全局變量的引用(安全)
}int& dangerous() {int local = 50;return local;   // 錯誤:返回局部變量的引用(懸空引用)
}
6.權限 放大 縮小 平移
int main()
{//權限不能放大//const int a = 0;//int& b = a;//可以只是一個拷貝const int c = 0;int d = c;//引用過程中權限可以平移或者縮小int x = 0;int& y = x;//權限的平移const int& z = x;//權限的縮小++x;//可以,因為上面是縮小了z的權限//不可以++z;double dd = 1.11;int ii = dd;//  不可以   int& rii = dd;const int& rii = dd;//臨時變量具有常性return 0;
}
引用 vs 指針
特性引用指針
初始化必須初始化可以聲明后賦值
重新綁定不能可以
空值不能為空可以為?nullptr
內存占用無獨立內存地址有自己的內存地址
語法簡潔性直接操作對象(無需?*?或?->需要解引用操作符(*?或?->

二.內聯函數

內聯函數建議編譯器將函數體直接插入調用位置(類似宏展開),以減少函數調用的開銷(壓棧、跳轉、返回等)。適用于短小且頻繁調用的函數。

#include <iostream>// 1. 使用 inline 關鍵字聲明內聯函數
inline int add(int a, int b) {return a + b;
}// 2. 類內定義的成員函數默認是內聯的
class Calculator {
public:int multiply(int a, int b) {  // 隱式內聯return a * b;}inline int subtract(int a, int b) {  // 顯式內聯return a - b;}
};int main() {int x = 5, y = 3;// 調用內聯函數 addstd::cout << "加法結果: " << add(x, y) << std::endl;  // 編譯器可能直接替換為 x + yCalculator calc;// 調用類內聯函數std::cout << "乘法結果: " << calc.multiply(x, y) << std::endl;std::cout << "減法結果: " << calc.subtract(x, y) << std::endl;return 0;
}
關鍵點說明
  1. inline?關鍵字
    用于建議編譯器將函數內聯,但最終是否內聯由編譯器決定(可通過編譯器優化選項控制,如?-O2)。

  2. 類成員函數的內聯性

    • 在類內部直接定義的成員函數(如?multiply)默認是內聯的。
    • 也可以在類外定義成員函數時使用?inline?關鍵字(需在頭文件中實現)。
  3. 適用場景

    • 函數體短小(如 1-3 行代碼)。
    • 頻繁調用且對性能敏感的場景(如循環中的操作)。
  4. 注意事項

    • 避免內聯復雜函數(如遞歸函數或包含循環的函數)。
    • 內聯函數定義必須對調用者可見,通常直接寫在頭文件中。

三.宏函數

?優點-- 不需要建立棧幀,提高調用效率
?缺點-- 復雜,容易出錯、可讀性差、不能調試

舉例三個問題的宏函數

Add(a | b, a & b); // (a | b + a & b)

為例:
以下三個有問題:

#define Add(int x, int y) return (x+y);
#define Add(x, y) x+y
#define Add(x, y) (x+y)

原因:(+ 與- 的優先級大于| 與&)

成功示范:
?

#define Add(x, y) ((x)+(y))

四.類

什么是類?
  • 是對象的“藍圖”或“模板”,用于定義對象的屬性(成員變量)行為(成員函數)
  • 通過類可以創建具體的對象(實例),每個對象擁有獨立的屬性值。
  • 類的核心思想是封裝:將數據和對數據的操作綁定在一起,并控制外部對數據的訪問權限。

簡單的類
#include <iostream>
using namespace std;// 定義一個 Person 類
class Person {
public: // 公有成員,外部可以直接訪問char name;  // 成員變量:姓名int age;      // 成員變量:年齡// 成員函數:顯示信息void display() {cout << "姓名: " << name << ", 年齡: " << age << endl;}
};int main() {// 創建 Person 類的對象Person person1;// 設置對象的屬性person1.name = "張三";person1.age = 25;// 調用對象的方法person1.display(); // 輸出:姓名: 張三, 年齡: 25return 0;
}

封裝:通過?private?隱藏內部細節,通過?public?提供安全接口

五.構造函數與析構函數

1. 構造函數(Constructor)

作用

  • 在對象創建時自動調用,用于初始化對象的成員變量。
  • 可以重載(定義多個不同參數的構造函數)。
  • 沒有返回類型,且名稱與類名相同

默認構造函數:無參構造函數,全缺省構造函數,編譯器默認生成的構造函數

示例

構造函數:

class Person {
public:char name;int age;// 默認構造函數(無參數)Person() {name = "Unknown";age = 0;cout << "默認構造函數被調用" << endl;}// 帶參數的構造函數Person(string n, int a) {name = n;age = a;cout << "帶參數的構造函數被調用" << endl;}
};
使用環境:
int main() {Person p1;                // 調用默認構造函數Person p2("Alice", 25);   // 調用帶參數的構造函數return 0;
}
2. 析構函數(Destructor)
作用
  • 在對象銷毀時自動調用,用于釋放對象占用的資源(如內存、文件句柄)。
  • 名稱是類名前加?~沒有參數和返回類型
  • 不能重載(每個類只有一個析構函數)。
示例

析構函數:

class FileHandler {
private:FILE* file;
public:// 構造函數:打開文件FileHandler(const char* filename) {file = fopen(filename, "r");cout << "文件已打開" << endl;}// 析構函數:關閉文件~FileHandler() {if (file) {fclose(file);cout << "文件已關閉" << endl;}}
};

使用場景:
?

int main() {Person p1;                // 調用默認構造函數Person p2("Alice", 25);   // 調用帶參數的構造函數return 0;
}
總結
特性構造函數析構函數
調用時機對象創建時對象銷毀時
主要用途初始化成員變量釋放資源(如內存、文件)
重載支持重載(多個構造函數)不支持重載(唯一析構函數)
默認生成未定義時編譯器生成默認構造函數未定義時編譯器生成默認析構函數

通過合理使用構造函數和析構函數,可以確保對象在生命周期內正確初始化和清理資源,避免內存泄漏和邏輯錯誤。

六.this指針

1.?什么是?this?指針?

在 C++ 中,this?是一個指向當前對象的指針

  • 每個類的非靜態成員函數(包括構造函數和析構函數)內部都可以訪問?this
  • this?指針是隱式存在的,不需要手動定義。
  • 它的類型是?ClassName*(例如,Person*Car*)。
class Person {
public:string name;void printName() {// 實際上等價于:cout << this->name << endl;cout << name << endl;}
};

2. 為什么需要?this?指針?

當你在類的成員函數中訪問成員變量或調用成員函數時,編譯器實際上是通過?this?指針來找到當前對象的成員
例如:

class Person {
public:string name;void printName() {// 實際上等價于:cout << this->name << endl;cout << name << endl;}
};

3.?注意事項

this?是一個指針靜態函數屬于類,而不是對象,因此不能使用?this。this指針是形參所以是存在棧中的

class MyClass {
public:static void staticFunc() {// this->xxx;  // 錯誤!靜態函數沒有 this}
};

七.拷貝構造函數

一、什么是拷貝構造函數?

拷貝構造函數是一個特殊的構造函數,用于通過已存在的對象創建一個新對象。當發生以下情況時會自動調用:

  1. 用已有對象初始化新對象
  2. 對象作為函數參數傳遞(值傳遞)
  3. 對象作為函數返回值(值返回)

基本語法:

ClassName(const ClassName& other);
二、淺拷貝(Shallow Copy)
什么是淺拷貝?
  • 默認的拷貝構造函數是淺拷貝
  • 直接復制成員變量的值(包括指針地址)
  • 如果類中有指針成員,會導致多個對象指向同一塊內存
淺拷貝的問題
class ShallowCopy {
public:int* data;//構造函數ShallowCopy(int val) {data = new int(val); // 動態分配內存}// 默認拷貝構造函數是淺拷貝:ShallowCopy(const ShallowCopy& other) = default;//析構函數~ShallowCopy() {delete data; // 釋放內存}
};int main() {ShallowCopy obj1(10);ShallowCopy obj2 = obj1; // 淺拷貝// 問題:obj1和obj2的data指向同一塊內存// 當main結束時,obj2先調用析構函數釋放內存// 然后obj1的析構函數會嘗試釋放已釋放的內存 → 程序崩潰!
}
三、深拷貝(Deep Copy)
什么是深拷貝?
  • 需要手動實現拷貝構造函數
  • 為指針成員分配新的內存
  • 復制指針指向的內容,而不是復制指針地址
深拷貝解決方案
class DeepCopy {
public:int* data;DeepCopy(int val) {data = new int(val);}// 手動實現深拷貝構造函數DeepCopy(const DeepCopy& other) {data = new int(*other.data); // 分配新內存并復制值}// 注意:還需要重載賦值運算符(規則同理)DeepCopy& operator=(const DeepCopy& other) {if (this != &other) {delete data;            // 釋放原有內存data = new int(*other.data); // 深拷貝}return *this;}~DeepCopy() {delete data;}
};int main() {DeepCopy obj1(20);DeepCopy obj2 = obj1; // 深拷貝// obj1.data 和 obj2.data 指向不同內存// 析構時不會出現重復釋放問題
}
四、關鍵總結
淺拷貝深拷貝
復制內容復制指針地址復制指針指向的內容
內存安全性多個對象共享同一內存,易導致崩潰每個對象擁有獨立內存,安全可靠
實現方式默認拷貝構造函數需要手動實現拷貝構造函數
適用場景無動態內存分配的簡單類有指針成員或動態分配資源的類

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/71553.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/71553.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/71553.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vsan數據恢復—vsan緩存盤故障導致虛擬磁盤文件丟失的數據恢復案例

vsan數據恢復環境&故障&#xff1a; VMware vsan架構采用21模式。每臺設備只有一個磁盤組&#xff08;71&#xff09;&#xff0c;緩存盤的大小為240GB&#xff0c;容量盤的大小為1.2TB。 由于其中一臺主機&#xff08;0號組設備&#xff09;的緩存盤出現故障&#xff0c;導…

開源在線考試系統開源在線考試系統:支持數學公式的前后端分離解決方案

開源在線考試系統&#xff1a;支持數學公式的前后端分離解決方案 項目介紹項目概述&#xff1a;技術棧&#xff1a;版本要求主要功能&#xff1a;特色亮點 項目倉庫地址演示地址GiteeGitHub 系統效果展示教師端系統部分功能截圖學生端系統部分功能截圖 結語 項目介紹 項目概述…

redis解決高并發看門狗策略

當一個業務執行時間超過自己設定的鎖釋放時間&#xff0c;那么會導致有其他線程進入&#xff0c;從而搶到同一個票,所有需要使用看門狗策略&#xff0c;其實就是開一個守護線程&#xff0c;讓守護線程去監控key&#xff0c;如果到時間了還未結束&#xff0c;就會將這個key重新s…

新數據結構(12)——代理

什么是代理 在進行操作時有時不希望用戶直接接觸到目標&#xff0c;這時需要使用代理讓用戶間接接觸到目標 給目標對象提供一個代理對象&#xff0c;并且由代理對象控制著對目標對象的引用 圖解&#xff1a; 代理的目的 控制訪問&#xff1a;通過代理對象的方式間接的訪問目…

Unity Shader Graph 2D - Procedural程序化圖形之夾心圓環

前言 本文將使用Unity Shader Graph的節點來繪制一個夾心圓環,分成三部分外環、內環和中心環。通過制作一個夾心圓環能夠更好地理解和實踐Shader Graph中的基礎節點以及思維。 創建一個Ring的Shader Graph文件,再創建一個對應的材質球M_Ring以及一個Texture2D的MainT…

緩存三大問題及其解決方案

緩存三大問題及其解決方案 1. 前言 ? 在現代系統架構中&#xff0c;緩存與數據庫的結合使用是一種經典的設計模式。為了確保緩存中的數據與數據庫中的數據保持一致&#xff0c;通常會給緩存數據設置一個過期時間。當系統接收到用戶請求時&#xff0c;首先會訪問緩存。如果緩…

【算法】----多重背包問題I,II(動態規劃)

&#x1f339;作者:云小逸 &#x1f4dd;個人主頁:云小逸的主頁 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一個人默默的面對自己&#xff0c;強大自己才是核心。不要等到什么都沒有了&#xff0c;才下定決心去做。種一顆樹&#xff0c;最好的時間是十年前…

LeetCode-524. 通過刪除字母匹配到字典里最長單詞

1、題目描述&#xff1a; 給你一個字符串 s 和一個字符串數組 dictionary &#xff0c;找出并返回 dictionary 中最長的字符串&#xff0c;該字符串可以通過刪除 s 中的某些字符得到。 如果答案不止一個&#xff0c;返回長度最長且字母序最小的字符串。如果答案不存在&#x…

TikTok賬戶安全指南:如何取消兩步驗證?

TikTok賬戶安全指南&#xff1a;如何取消兩步驗證&#xff1f; 在這個數字化的時代&#xff0c;保護我們的在線賬戶安全變得尤為重要。TikTok&#xff0c;作為全球流行的社交媒體平臺&#xff0c;其賬戶安全更是不容忽視。兩步驗證作為一種增強賬戶安全性的措施&#xff0c;雖…

面試題之箭頭函數和普通函數有什么區別?

箭頭函數&#xff08;Arrow Function&#xff09;和普通函數&#xff08;Regular Function&#xff09;是 JavaScript 中兩種不同的函數定義方式&#xff0c;它們在語法、上下文&#xff08;this&#xff09;、原型鏈等方面存在顯著區別。以下是它們的主要區別&#xff1a; 1. …

Llama 3.1 本地電腦部署 Linux系統 【輕松簡易】

本文分享在自己的本地電腦部署 llama3.1&#xff0c;而且輕松簡易&#xff0c;快速上手。 這里借助Ollama工具&#xff0c;在Linux系統中進行大模型部署~ Llama3.1&#xff0c;有三個版本&#xff1a;8B、70B、405B Llama 3.1 405B 是第一個公開可用的模型&#xff0c;在常識…

工業安全的智能哨兵:AI如何筑起生產線的“數字防火墻“

工業安全的智能哨兵:AI如何筑起生產線的"數字防火墻" (本文共1420字,閱讀約需4分鐘) 去年某石化廠的反應釜壓力數據出現異常波動,傳統監測系統在15分鐘后才發出警報——而AI模型在23秒前就已預警。這場未遂事故揭示了一個殘酷現實:工業安全監測正在經歷從&qu…

【Bert】自然語言(Language Model)入門之---Bert

every blog every motto: Although the world is full of suffering&#xff0c; it is full also of the overcoming of it 0. 前言 對bert進行梳理 論文&#xff1a; BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 時間&#xff1a;…

Linux中使用Docker安裝DIFY搭建本地支持庫和Agent

Dify 是一款開源的大語言模型(LLM) 應用開發平臺。它融合了后端即服務&#xff08;Backend as Service&#xff09;和 LLMOps 的理念&#xff0c;使開發者可以快速搭建生產級的生成式 AI 應用。即使你是非技術人員&#xff0c;也能參與到 AI 應用的定義和數據運營過程中。 然而…

開源工具推薦--思維導圖、流程圖等繪制

1. 前言 在工作中&#xff0c;經常要用到各種不同的工具&#xff0c;隨著系統的升級&#xff0c;有些工具也在不斷更新升級。這里收集整理一些好用的開源工具推薦&#xff0c;遵循以下一些基本原則&#xff1a;開源免費&#xff0c;商業工具的有效平替&#xff0c;輕量級&…

Ubuntu 下 nginx-1.24.0 源碼分析 - ngx_create_pool函數

ngx_create_pool 聲明在 src\core\ngx_palloc.h 中 ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log); 實現在 src\core\ngx_palloc.c 中 ngx_pool_t * ngx_create_pool(size_t size, ngx_log_t *log) {ngx_pool_t *p;p ngx_memalign(NGX_POOL_ALIGNMENT, size, lo…

ac的dhcp池里option43配錯導致ap無法上線問題排查過程

dhcp池里ac地址配錯&#xff0c;導致ap無法上線問題排查過程 問題&#xff1a;ap手動設置ac的ip正常注冊在線&#xff0c;但dhcp獲得ip和ac地址發現無法在ac上注冊成功。 組網&#xff1a; ac旁路結構&#xff0c;路由器lan口地址172.16.1.1&#xff0c;開dhcp服務&#xff0…

IntelliJ IDEA中Maven配置全指南

一、環境準備與基礎配置 1.1 Windows 環境下載并配置 Maven 見此篇博文&#xff1a;環境配置 1.2 IDEA配置步驟 打開設置面板&#xff1a;File → Settings → Build → Build Tools → Maven 關鍵配置項&#xff1a; Maven home path E:\apache-maven-3.9.9 &#xff08;…

存儲區域網絡(SAN)管理

存儲區域網絡&#xff08;Storage Area Network&#xff0c;SAN&#xff09;采用網狀通道&#xff08;Fibre Channel &#xff0c;簡稱FC&#xff09;技術&#xff0c;通過FC交換機連接存儲陣列和服務器主機&#xff0c;建立專用于數據存儲的區域網絡。SAN提供了一種與現有LAN連…

使用vue-office報錯TypeError: ft.createElementVNode is not a function

支持多種文件(.docx、.xlsx、.xls、.pdf、.pptx)預覽的vue組件庫&#xff0c;支持vue2/3。也支持非Vue框架的預覽。 不支持.doc、.ppt&#xff08;2003年及以前的版本&#xff09; 官網&#xff1a;https://www.npmjs.com/package/vue-office/excel?activeTabreadme 官方有實…