最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ 類和對象從基礎(chǔ)語法到高級特性深度解析

 更新時間:2026年01月10日 11:43:41   作者:xie_pin_an  
本文深入探討了C++類和對象的核心概念,包括類的定義、訪問控制、實例化、this指針、默認成員函數(shù)(構(gòu)造、析構(gòu)、拷貝構(gòu)造、賦值重載)、以及高級特性,感興趣的朋友跟隨小編一起看看吧

在 C++ 編程中,類和對象是面向?qū)ο缶幊蹋∣OP)的核心基石,封裝、繼承、多態(tài)三大特性均圍繞其展開。本文將從類的定義與實例化、默認成員函數(shù)、高級特性等維度,結(jié)合實戰(zhàn)代碼,系統(tǒng)梳理類和對象的關(guān)鍵知識點,幫助開發(fā)者夯實 OOP 基礎(chǔ)。

一、類的基礎(chǔ)認知:定義、訪問控制與實例化

1.1 類的定義格式

C++ 使用class關(guān)鍵字定義類(struct也可定義類,兼容 C 語言用法且支持成員函數(shù)),類體包含成員變量(屬性)和成員函數(shù)(方法),結(jié)束時必須加分號。為區(qū)分成員變量與局部變量,慣例是給成員變量加前綴(如_)或后綴,例如_year、m_month。

class Date {
public:
    // 成員函數(shù):初始化日期
    void Init(int year, int month, int day) {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    // 成員變量:加前綴_區(qū)分
    int _year;
    int _month;
    int _day;
}; // 分號不可省略

1.2 訪問限定符:封裝的核心實現(xiàn)

訪問限定符控制成員的訪問權(quán)限,是封裝特性的直接體現(xiàn):

  • public:類外可直接訪問(通常暴露接口函數(shù));
  • private/protected:類外不可直接訪問(通常隱藏成員變量,繼承時二者有差異);
  • 訪問權(quán)限作用域:從限定符出現(xiàn)位置到下一個限定符結(jié)束,class默認privatestruct默認public。

1.3 類域與成員函數(shù)分離

類定義了獨立的作用域,類外實現(xiàn)成員函數(shù)時需用::作用域操作符指明所屬類,否則編譯器會視為全局函數(shù)。

// 類內(nèi)聲明,類外實現(xiàn)
void Date::Init(int year, int month, int day) {
    _year = year;
    _month = month;
    _day = day;
}

1.4 類的實例化

類是對象的 “設(shè)計圖”,僅聲明成員變量(未分配空間),實例化是通過類創(chuàng)建對象并分配物理內(nèi)存的過程。一個類可實例化多個對象,每個對象擁有獨立的成員變量存儲空間,成員函數(shù)則共享(存儲在代碼段)。

int main() {
    Date d1; // 實例化對象d1,分配內(nèi)存
    d1.Init(2024, 10, 1); // 調(diào)用成員函數(shù)初始化
    return 0;
}

1.5 對象大小計算

對象僅存儲成員變量,大小遵循內(nèi)存對齊規(guī)則(與結(jié)構(gòu)體一致),目的是提高訪問效率:

  1. 第一個成員偏移量為 0;
  2. 其他成員對齊到 “對齊數(shù)”(編譯器默認值與成員大小的較小值,VS 默認 8)的整數(shù)倍;
  3. 總大小為最大對齊數(shù)的整數(shù)倍;
  4. 無成員變量的類對象大小為 1 字節(jié)(占位標(biāo)識對象存在)。
class A {
private:
    char _ch; // 1字節(jié)
    int _i;   // 4字節(jié),對齊數(shù)4
};
// 內(nèi)存對齊后大?。?字節(jié)(1+3填充+4)
cout << sizeof(A) << endl; // 輸出8

二、this 指針:對象的 “隱藏身份標(biāo)識”

2.1 核心問題

多個對象共享成員函數(shù),函數(shù)如何區(qū)分操作的是哪個對象?例如d1.Init()d2.Init(),函數(shù)需知道當(dāng)前操作的是d1還是d2。

2.2 本質(zhì)與特性

C++ 編譯器在成員函數(shù)形參第一個位置隱含添加this指針(類型為類名* const),指向當(dāng)前調(diào)用函數(shù)的對象,函數(shù)體內(nèi)訪問成員變量本質(zhì)是通過this指針訪問(可顯式使用,不可顯式聲明)。

// 編譯器優(yōu)化后的Init函數(shù)原型
void Date::Init(Date* const this, int year, int month, int day) {
    this->_year = year; // 顯式使用this
    _month = month;    // 隱式使用this
}
// 調(diào)用時編譯器自動傳遞對象地址
d1.Init(2024, 10, 1); // 等價于d1.Init(&d1, 2024, 10, 1)

2.3 經(jīng)典面試題解析

// 題目1:編譯運行結(jié)果?
class A {
public:
    void Print() { cout << "A::Print()" << endl; }
private:
    int _a;
};
int main() {
    A* p = nullptr;
    p->Print(); // 正常運行:Print未訪問成員變量,無需解引用p
    return 0;
}
// 題目2:編譯運行結(jié)果?
class A {
public:
    void Print() { cout << _a << endl; } // 訪問成員變量,需解引用this
private:
    int _a;
};
int main() {
    A* p = nullptr;
    p->Print(); // 運行崩潰:this為nullptr,解引用出錯
    return 0;
}

三、默認成員函數(shù):編譯器的 “自動實現(xiàn)”

當(dāng)用戶未顯式定義時,編譯器會自動生成 6 個默認成員函數(shù),核心是前 4 個:構(gòu)造、析構(gòu)、拷貝構(gòu)造、賦值重載。

3.1 構(gòu)造函數(shù):對象的 “初始化器”

  • 功能:替代Init函數(shù),對象實例化時自動調(diào)用,初始化成員變量;
  • 特性
    1. 函數(shù)名與類名相同,無返回值(無需寫void);
    2. 可重載(無參、帶參、全缺?。?/li>
    3. 無顯式定義時,編譯器生成默認構(gòu)造(對內(nèi)置類型不初始化,自定義類型調(diào)用其默認構(gòu)造);
    4. 無參、全缺省、編譯器默認生成的構(gòu)造,統(tǒng)稱 “默認構(gòu)造”(不傳參即可調(diào)用)。
class Date {
public:
    // 全缺省構(gòu)造(推薦,兼顧多種初始化場景)
    Date(int year = 1, int month = 1, int day = 1) {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    int _year;
    int _month;
    int _day;
};
// 實例化方式
Date d1; // 調(diào)用全缺省構(gòu)造,默認1-1-1
Date d2(2024, 10, 1); // 調(diào)用帶參構(gòu)造

3.2 析構(gòu)函數(shù):對象的 “清理工”

  • 功能:替代Destroy函數(shù),對象生命周期結(jié)束時自動調(diào)用,釋放資源(如堆內(nèi)存);
  • 特性
    1. 函數(shù)名~類名,無參數(shù)無返回值;
    2. 一個類僅一個析構(gòu)函數(shù)(不可重載);
    3. 無顯式定義時,編譯器生成默認析構(gòu)(對內(nèi)置類型不處理,自定義類型調(diào)用其析構(gòu));
    4. 有資源申請(如mallocnew)時必須顯式定義,否則內(nèi)存泄漏。
class Stack {
public:
    Stack(int n = 4) {
        _a = (int*)malloc(sizeof(int) * n);
        _capacity = n;
        _top = 0;
    }
    // 顯式定義析構(gòu),釋放堆內(nèi)存
    ~Stack() {
        free(_a);
        _a = nullptr;
        _top = _capacity = 0;
    }
private:
    int* _a;
    size_t _capacity;
    size_t _top;
};

3.3 拷貝構(gòu)造函數(shù):對象的 “復(fù)制器”

  • 功能:用已有對象初始化新對象(如Date d2 = d1);
  • 特性
    1. 第一個參數(shù)必須是const 類名&(傳值會引發(fā)無窮遞歸),后續(xù)參數(shù)可帶默認值;
    2. 無顯式定義時,編譯器生成默認拷貝構(gòu)造(內(nèi)置類型值拷貝 / 淺拷貝,自定義類型調(diào)用其拷貝構(gòu)造);
    3. 淺拷貝問題:若成員變量指向堆內(nèi)存(如Stack_a),會導(dǎo)致多個對象共享同一塊內(nèi)存,析構(gòu)時重復(fù)釋放崩潰,需顯式實現(xiàn)深拷貝。
Stack::Stack(const Stack& st) {
    // 深拷貝:為新對象分配獨立內(nèi)存
    _a = (int*)malloc(sizeof(int) * st._capacity);
    if (_a == nullptr) perror("malloc fail");
    memcpy(_a, st._a, sizeof(int) * st._top);
    _top = st._top;
    _capacity = st._capacity;
}

3.4 賦值運算符重載:對象的 “賦值器”

  • 功能:兩個已存在對象間的賦值(如d1 = d2),區(qū)別于拷貝構(gòu)造(初始化新對象);
  • 特性
    1. 必須重載為成員函數(shù),函數(shù)原型類名& operator=(const 類名&);
    2. 返回類名&支持連續(xù)賦值(如d1 = d2 = d3);
    3. 需檢查自賦值(if (this != &d)),避免重復(fù)釋放;
    4. 無顯式定義時,編譯器生成默認賦值重載(淺拷貝,需資源的類需顯式實現(xiàn)深拷貝)。
Date& Date::operator=(const Date& d) {
    if (this != &d) { // 避免自賦值
        _year = d._year;
        _month = d._month;
        _day = d._day;
    }
    return *this; // 支持連續(xù)賦值
}

四、高級特性:提升代碼靈活性與效率

4.1 初始化列表:成員變量的 “初始化源頭”

  • 格式:構(gòu)造函數(shù)后加:,后跟成員變量初始化表達式(成員變量(值), ...);
  • 必要性:引用成員、const成員、無默認構(gòu)造的自定義類型成員,必須通過初始化列表初始化;
  • 注意:初始化順序與類中成員聲明順序一致,與列表順序無關(guān)。
class Date {
public:
    // 初始化列表初始化
    Date(int year, int month, int day, int& ref)
        : _year(year)
        , _month(month)
        , _day(day)
        , _ref(ref) // 引用必須初始化
        , _n(10)    // const成員必須初始化
    {}
private:
    int _year;
    int _month;
    int _day;
    int& _ref;    // 引用成員
    const int _n; // const成員
};

4.2 static 成員:類的 “共享資源”

  • 靜態(tài)成員變量
    1. static修飾,所有對象共享,存儲在靜態(tài)區(qū);
    2. 類內(nèi)聲明,類外初始化(類型 類名::變量名 = 值);
    3. 受訪問限定符控制,可通過類名::變量對象.變量訪問。
  • 靜態(tài)成員函數(shù)
    1. static修飾,無this指針;
    2. 僅可訪問靜態(tài)成員變量 / 函數(shù),不可訪問非靜態(tài)成員。

應(yīng)用場景:統(tǒng)計對象創(chuàng)建個數(shù):

class A {
public:
    A() { ++_scount; }
    A(const A&) { ++_scount; }
    ~A() { --_scount; }
    static int GetCount() { return _scount; } // 靜態(tài)成員函數(shù)
private:
    static int _scount; // 靜態(tài)成員變量
};
int A::_scount = 0; // 類外初始化
int main() {
    A a1, a2;
    cout << A::GetCount() << endl; // 輸出2
    return 0;
}

4.3 友元:突破封裝的 “特殊權(quán)限”

友元允許外部函數(shù) / 類訪問類的私有成員,分為友元函數(shù)和友元類,慎用(破壞封裝)。

  • 友元函數(shù):非成員函數(shù),類內(nèi)聲明時加friend;
  • 友元類:類 A 是類 B 的友元,則 A 的所有成員函數(shù)可訪問 B 的私有成員(單向關(guān)系,不可傳遞)。
class Date {
    // 友元聲明:operator<<可訪問私有成員
    friend ostream& operator<<(ostream& out, const Date& d);
private:
    int _year;
    int _month;
    int _day;
};
// 全局函數(shù)實現(xiàn)
ostream& operator<<(ostream& out, const Date& d) {
    out << d._year << "-" << d._month << "-" << d._day;
    return out;
}
// 使用
Date d(2024, 10, 1);
cout << d << endl; // 輸出2024-10-1

4.4 匿名對象:臨時使用的 “無名稱對象”

  • 格式類名(實參),生命周期僅當(dāng)前行;
  • 場景:臨時調(diào)用成員函數(shù),無需定義命名對象。
class Solution {
public:
    int Sum(int n) { return n*(n+1)/2; }
};
// 匿名對象調(diào)用函數(shù)
int ret = Solution().Sum(100); // 輸出5050

五、C++ vs C 語言:封裝的優(yōu)勢

Stack為例,對比 C 語言與 C++ 的實現(xiàn)差異:

特性C 語言實現(xiàn)C++ 實現(xiàn)
數(shù)據(jù)與函數(shù)關(guān)系分離(函數(shù)需顯式傳結(jié)構(gòu)體指針)封裝(數(shù)據(jù) + 函數(shù)在類內(nèi),this 指針隱式傳遞)
訪問控制無,可直接修改結(jié)構(gòu)體成員訪問限定符控制,私有成員不可直接修改
初始化與清理需手動調(diào)用Init/Destroy構(gòu)造 / 析構(gòu)函數(shù)自動調(diào)用,避免遺漏
代碼簡潔性需 typedef,函數(shù)參數(shù)繁瑣類名直接作為類型,語法更簡潔

六、總結(jié)

類和對象是 C++ 面向?qū)ο缶幊痰暮诵模诵囊c可概括為:

  1. 封裝:通過類整合數(shù)據(jù)與函數(shù),訪問限定符控制權(quán)限;
  2. 默認成員函數(shù):構(gòu)造(初始化)、析構(gòu)(清理)、拷貝構(gòu)造(復(fù)制新對象)、賦值重載(對象賦值)是基礎(chǔ),需區(qū)分使用場景;
  3. 高級特性:初始化列表解決特殊成員初始化,static 成員實現(xiàn)共享資源,友元靈活訪問私有成員(慎用),匿名對象簡化臨時操作;
  4. 內(nèi)存與效率:理解 this 指針、內(nèi)存對齊、編譯器拷貝優(yōu)化,避免內(nèi)存泄漏和性能問題。

到此這篇關(guān)于C++ 類和對象全解析:從基礎(chǔ)語法到高級特性的文章就介紹到這了,更多相關(guān)C++ 類和對象內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

屏东县| 吉首市| 马鞍山市| 澳门| 尚志市| 武汉市| 阿尔山市| 民勤县| 聂荣县| 定襄县| 博乐市| 清涧县| 山东| 孟连| 景宁| 沧源| 洛南县| 荆门市| 德格县| 温泉县| 渭南市| 安顺市| 东莞市| 汶上县| 乌鲁木齐县| 玛多县| 陈巴尔虎旗| 赤壁市| 蒙城县| 马山县| 嵊泗县| 田林县| 大埔县| 治多县| 越西县| 澄江县| 东安县| 平泉县| 澄江县| 新绛县| 东乡县|