亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++類與對象的重點知識點詳細分析

 更新時間:2023年02月13日 10:46:56   作者:Ggggggtm  
類和對象是兩種以計算機為載體的計算機語言的合稱。對象是對客觀事物的抽象,類是對對象的抽象。類是一種抽象的數(shù)據(jù)類型;變量就是可以變化的量,存儲在內(nèi)存中—個可以擁有在某個范圍內(nèi)的可變存儲區(qū)域

一、類的六個默認成員函數(shù)詳解

我們這里接著C++類與對象的基礎知識點詳細分析來寫。C++類和對象概念及實現(xiàn)詳解上篇中我們重點解釋了類的儲存方式、類和對象的概念、this指針、構(gòu)造函數(shù)、析構(gòu)函數(shù)。這篇文章我們主要對剩余的四個默認成員函數(shù)拷貝構(gòu)造、賦值運算符重載、普通對象取地址、const對象取地址,以及運算符重載、友元函數(shù)、static成員等重點內(nèi)容進行詳解。

1、拷貝構(gòu)造

1.1 拷貝構(gòu)造的引入及概念

我們想象一下:在創(chuàng)建對象時,可否創(chuàng)建一個與已存在對象一摸一樣的新對象呢?答案是可以的。那怎么創(chuàng)建一個一樣的新對象呢?是自己對新對象初始化嗎?其實是不用的。C++在這里提供了一個默認的成員函數(shù),也就是拷貝構(gòu)造,來完成創(chuàng)建一個新的一摸一樣的對象。我們先來看一下拷貝構(gòu)造的概念。

拷貝構(gòu)造函數(shù):只有單個形參,該形參是對本類類型對象的引用(一般常用const修飾),在用已存在的類類型對象創(chuàng)建新對象時由編譯器自動調(diào)用。

1.2 拷貝構(gòu)造函數(shù)的特征

拷貝構(gòu)造函數(shù)也是特殊的成員函數(shù),其特征如下:

  • 拷貝構(gòu)造函數(shù)是構(gòu)造函數(shù)的一個重載形式。
  • 拷貝構(gòu)造函數(shù)的參數(shù)只有一個且必須是類類型對象的引用,使用傳值方式編譯器直接報錯,因為會引發(fā)無窮遞歸調(diào)用。
  • 若未顯式定義,編譯器會生成默認的拷貝構(gòu)造函數(shù)。 默認的拷貝構(gòu)造函數(shù)對象按內(nèi)存存儲按字節(jié)序完成拷貝,這種拷貝叫做淺拷貝,或者值拷貝。
  • 編譯器生成的默認拷貝構(gòu)造函數(shù)已經(jīng)可以完成字節(jié)序的值拷貝了,但是要注意的是類中如果沒有涉及資源申請時,拷貝構(gòu)造函數(shù)是否寫都可以;一旦涉及到資源申請時,則拷貝構(gòu)造函數(shù)是一定要寫的,否則就是淺拷貝。
  • 拷貝構(gòu)造函數(shù)典型調(diào)用場景:使用已存在對象創(chuàng)建新對象、函數(shù)參數(shù)類型為類類型對象、函數(shù)返回值類型為類類型對象。

特征2中提到,形參必須是類類型對象的引用,使用傳值的話為什么會引發(fā)我窮遞歸呢?因為我們傳的實參是自定義類,傳值的形參初始化是實參調(diào)用拷貝構(gòu)造函數(shù)完成的。下一個拷貝構(gòu)造函數(shù)形參初始化又要調(diào)用拷貝構(gòu)造函數(shù),所以會無限遞歸。

特征3需要注意的是:在編譯器生成的默認拷貝構(gòu)造函數(shù)中,內(nèi)置類型是按照字節(jié)方式直接拷貝的,而自定義類型是調(diào)用其拷貝構(gòu)造函數(shù)完成拷貝的。我們結(jié)合著以下代碼理解一下。

class Time
{
public:
    Time()
    {
        _hour = 1;
        _minute = 1;
        _second = 1;
    }
    Time(const Time& t)
    {
        _hour = t._hour;
        _minute = t._minute;
        _second = t._second;
        cout << "Time::Time(const Time&)" << endl;
    }
private:
    int _hour;
    int _minute;
    int _second;
};
class Date
{
private:
    // 基本類型(內(nèi)置類型)
    int _year = 1970;
    int _month = 1;
    int _day = 1;
    // 自定義類型
    Time _t;
};
int main()
{
    Date d1;
    // 用已經(jīng)存在的d1拷貝構(gòu)造d2,此處會調(diào)用Date類的拷貝構(gòu)造函數(shù)
    // 但Date類并沒有顯式定義拷貝構(gòu)造函數(shù),則編譯器會給Date類生成一個默認的拷貝構(gòu)
    // 造函數(shù),_t為自定義類型,會自動調(diào)用自己的構(gòu)造函數(shù)完成拷貝
    Date d2(d1);
    return 0;
}

2、賦值運算符重載

2.1 運算符重載

在學習賦值運算符重載時,我們先學習一下運算符重載。

C++為了增強代碼的可讀性引入了運算符重載,運算符重載是具有特殊函數(shù)名的函數(shù),也具有其返回值類型,函數(shù)名字以及參數(shù)列表,其返回值類型與參數(shù)列表與普通的函數(shù)類似。

函數(shù)名字為:關鍵字operator后面接需要重載的運算符符號。 函數(shù)原型:返回值類型 operator操作符(參數(shù)列表)。

運算符重載有五個需要注意的點:

  • 不能通過連接其他符號來創(chuàng)建新的操作符:比如operator@;
  • 重載操作符必須有一個類類型參數(shù);
  • 用于內(nèi)置類型的運算符,其含義不能改變,例如:內(nèi)置的整型+,不能改變其含義;
  • 作為類成員函數(shù)重載時,其形參看起來比操作數(shù)數(shù)目少1,因為成員函數(shù)的第一個參數(shù)為隱藏的this;
  • .*  ::   sizeof   ?:   .   注意以上5個運算符不能重載。

大家可結(jié)合下面的例子來理解一下運算符重載。

class Date
{
public:
    Date(int year = 1900, int month = 1, int day = 1)
    {
    _year = year;
    _month = month;
    _day = day;
    }
// bool operator==(Date* this, const Date& d2)
// 這里需要注意的是,左操作數(shù)是this,指向調(diào)用函數(shù)的對象
bool operator==(const Date& d2)
{
    return _year == d2._year;
    && _month == d2._month
    && _day == d2._day;
}
private:
    int _year;
    int _month;
    int _day;
};
void Test ()
{
    Date d1(2022, 12, 26);
    Date d2(2022, 12, 27);
    cout<<(d1 == d2)<<endl;
}

2.2 賦值運算符重載

賦值運算符重載格式:

  • 參數(shù)類型:const T&,傳遞引用可以提高傳參效率;
  • 返回值類型:T&,返回引用可以提高返回的效率,有返回值目的是為了支持連續(xù)賦值;
  • 檢測是否自己給自己賦值;
  • 返回*this :要復合連續(xù)賦值的含義。

結(jié)合下面代碼理解。

class Date
{
public :
    Date(int year = 1900, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    Date (const Date& d)
    {
        _year = d._year;
        _month = d._month;
        _day = d._day;
    }
    Date& operator=(const Date& d)
    {
        if(this != &d)//判斷是否自己給自己復制
        {
            _year = d._year;
            _month = d._month;
            _day = d._day;
        }
        return *this;
    }
private:
    int _year ;
    int _month ;
    int _day ;
};

這里還有需要注意的是2賦值運算符只能重載成類的成員函數(shù)不能重載成全局函數(shù)。為什么呢?原因是賦值運算符如果在類中不顯式實現(xiàn),編譯器會生成一個默認的。此時用戶再在類外自己實現(xiàn)一個全局的賦值運算符重載,就和編譯器在類中生成的默認賦值運算符重載沖突了,故賦值運算符重載只能是類的成員函數(shù)。

用戶沒有顯式實現(xiàn)時,編譯器會生成一個默認賦值運算符重載,以值的方式逐字節(jié)拷貝(淺拷貝)。注意:內(nèi)置類型成員變量是直接賦值的,而自定義類型成員變量需要調(diào)用對應類的賦值運算符重載完成賦值。

3、普通對象取地址

普通對象取地址默認成員函數(shù)一般不用重新定義 ,編譯器默認會生成。一般編譯器自動生成的基本上會滿足我們的需求。理解起來也很簡單,我們直接看代碼。

class Date
{
    public :
    Date* operator&()
    {
        return this ;
    }
private :
    int _year ; // 年
    int _month ; // 月
    int _day ; // 日
};

我們這里直接返回this指針即可。

4、const對象取地址

const對象取地址與普通對象取地址大同小異,const修飾的對象內(nèi)容不可被更改,所以我們傳址的時候需要加上const修飾形參指針。我們直接看代碼。

class Date
{
public :
    const Date* operator&()const
    {
        return this ;
    }
private :
    int _year ; // 年
    int _month ; // 月
    int _day ; // 日
};

普通對象取地址、const對象取地址這兩個運算符一般不需要重載,使用編譯器生成要重載,比如想讓別人獲取到指定的內(nèi)容(返回空指針)!

二、類和對象重點知識點

1、初始化列表

class Date
{
public:
    Date(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    int _year;
    int _month;
    int _day;
};

雖然上述構(gòu)造函數(shù)調(diào)用之后,對象中已經(jīng)有了一個初始值,但是不能將其稱為對對象中成員變量的初始化,構(gòu)造函數(shù)體中的語句只能將其稱為賦初值,而不能稱作初始化。因為初始化只能初始化一次,而構(gòu)造函數(shù)體內(nèi)可以多次賦值

那對象的成員變量是在哪里初始化的呢?是在構(gòu)造函數(shù)的初始化列表進行的。

初始化列表:以一個冒號開始,接著是一個以逗號分隔的數(shù)據(jù)成員列表,每個"成員變量"后面跟一個放在括號中的初始值或表達式。我們結(jié)合下面代碼理解。

class Date
{
public:
    Date(int year, int month, int day)
        : _year(year)
        , _month(month)
        , _day(day)
        {}
private:
    int _year;
    int _month;
    int _day;
};

初始化列表需要注意的幾點:

  • 每個成員變量在初始化列表中只能出現(xiàn)一次(初始化只能初始化一次);
  • 引用成員變量、const成員變量、自定義類型成員(且該類沒有默認構(gòu)造函數(shù)時) ,這三個成員變量必須放在初始化列表位置進行初始化;
  • 盡量使用初始化列表初始化,因為不管你是否使用初始化列表,對于自定義類型成員變量,一定會先使用初始化列表初始化。
  • 成員變量在類中聲明次序就是其在初始化列表中的初始化順序,與其在初始化列表中的先后次序無關。

2、static成員

聲明為static的類成員稱為類的靜態(tài)成員,用static修飾的成員變量,稱之為靜態(tài)成員變量;用static修飾的成員函數(shù),稱之為靜態(tài)成員函數(shù)。靜態(tài)成員變量一定要在類外進行初始化

static修飾特征:

  • 靜態(tài)成員為所有類對象所共享,不屬于某個具體的對象,存放在靜態(tài)區(qū);
  • 靜態(tài)成員變量必須在類外定義,定義時不添加static關鍵字,類中只是聲明;
  • 類靜態(tài)成員即可用類名::靜態(tài)成員 或者對象.靜態(tài)成員來訪問;
  • 靜態(tài)成員函數(shù)沒有隱藏的this指針,不能訪問任何非靜態(tài)成員;
  • 靜態(tài)成員也是類的成員,受public、protected、private 訪問限定符的限制。

3、友元函數(shù)

我們都知道在類的外面是不能訪問私有成員的。那要是我們在類外面定義的函數(shù)必須要調(diào)用類的私有成員呢?這里C++提供了友元函數(shù)。

友元函數(shù)可以直接訪問類的私有成員,它是定義在類外部的普通函數(shù),不屬于任何類,但需要在類的內(nèi)部聲明,聲明時需要加friend關鍵字。

例如當我們實現(xiàn)運算符'>>'和‘<<’的重載時就使用到了友元函數(shù),我們看下面代碼。

class Date
{
    friend ostream& operator<<(ostream& _cout, const Date& d);
    friend istream& operator>>(istream& _cin, Date& d);
public:
    Date(int year = 1900, int month = 1, int day = 1)
    : _year(year)
    , _month(month)
    , _day(day)
    {}
private:
    int _year;
    int _month;
    int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{
    _cout << d._year << "-" << d._month << "-" << d._day;
    return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{
    _cin >> d._year;
    _cin >> d._month;
    _cin >> d._day;
    return _cin;
}
int main()
{
    Date d;
    cin >> d;
    cout << d << endl;
    return 0;
}   

友元函數(shù)說明:

  • 友元函數(shù)可訪問類的私有和保護成員,但不是類的成員函數(shù);
  • 友元函數(shù)不能用const修飾;
  • 友元函數(shù)可以在類定義的任何地方聲明,不受類訪問限定符限制;
  • 一個函數(shù)可以是多個類的友元函數(shù);
  • 友元函數(shù)的調(diào)用與普通函數(shù)的調(diào)用原理相同。

4、友元類

友元類的所有成員函數(shù)都可以是另一個類的友元函數(shù),都可以訪問另一個類中的非公有成員。

  • 友元關系是單向的,不具有交換性。
  • 比如上述Time類和Date類,在Time類中聲明Date類為其友元類,那么可以在Date類中直接
  • 訪問Time類的私有成員變量,但想在Time類中訪問Date類中私有的成員變量則不行。
  • 友元關系不能傳遞
  • 如果C是B的友元, B是A的友元,則不能說明C時A的友元。
class Time
{
    friend class Date; // 聲明日期類為時間類的友元類,則在日期類中就直接訪問Time類
                       // 中的私有成員變量
public:
    Time(int hour = 0, int minute = 0, int second = 0)
    : _hour(hour)
    , _minute(minute)
    , _second(second)
    {}
private:
    int _hour;
    int _minute;
    int _second;
};
class Date
{
public:
    Date(int year = 1900, int month = 1, int day = 1)
    : _year(year)
    , _month(month)
    , _day(day)
    {}
    void SetTimeOfDate(int hour, int minute, int second)
    {
        // 直接訪問時間類私有的成員變量
        _t._hour = hour;
        _t._minute = minute;
        _t._second = second;
    }
private:
    int _year;
    int _month;
    int _day;
    Time _t;
};

總結(jié)

類和對象細節(jié)較多,也是相對來叔十分重要的一部分,需要我們重點但掌握六個默認成員函數(shù)、類和對象的基本定義、this指針、static成員、初始化列表、友元函數(shù)和友元類。反復學習達到熟能生巧。

到此這篇關于C++類與對象的重點知識點詳細分析的文章就介紹到這了,更多相關C++類與對象內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++填坑的重寫,重載和隱藏的詳解

    C++填坑的重寫,重載和隱藏的詳解

    這篇文章主要介紹了C++中重載、重寫(覆蓋)和隱藏的區(qū)別,是C++面向?qū)ο蟪绦蛟O計非常重要的概念,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-09-09
  • C語言鏈表實現(xiàn)銷售管理系統(tǒng)

    C語言鏈表實現(xiàn)銷售管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言鏈表實現(xiàn)銷售管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C++中CSTRINGLIST用法詳解

    C++中CSTRINGLIST用法詳解

    這篇文章主要介紹了C++中CSTRINGLIST用法詳解的相關資料,需要的朋友可以參考下
    2015-06-06
  • C語言詳解select函數(shù)的使用

    C語言詳解select函數(shù)的使用

    C語言中select函數(shù)的使用?一般用connect、accept、recv或recvfrom這類函數(shù),程序阻塞,直至該套接字上接受到數(shù)據(jù)后程序才能繼續(xù)運行。但是使用select函數(shù)可以實現(xiàn)非阻塞方式的程序
    2022-05-05
  • C++友元(Friend)用法實例簡介

    C++友元(Friend)用法實例簡介

    這篇文章主要介紹了C++友元(Friend)用法,對于C++的學習來說有很好的參考價值,需要的朋友可以參考下
    2014-08-08
  • c語言程序調(diào)試方法整理

    c語言程序調(diào)試方法整理

    在本篇文章里小編給大家正里的是關于c語言程序調(diào)試方法整理內(nèi)容,需要的朋友們可以學習下。
    2020-03-03
  • C++ 非遞歸實現(xiàn)二叉樹的前中后序遍歷

    C++ 非遞歸實現(xiàn)二叉樹的前中后序遍歷

    本文將結(jié)合動畫和代碼演示如何通過C++ 非遞歸實現(xiàn)二叉樹的前中后序的遍歷,代碼具有一定的價值,感興趣的同學可以學習一下
    2021-11-11
  • Window10下安裝VS2022社區(qū)版的實現(xiàn)步驟(圖文教程)

    Window10下安裝VS2022社區(qū)版的實現(xiàn)步驟(圖文教程)

    很多和同學們在接觸c語言的時候都是使用VS,本文主要介紹了Window10下如何安裝VS2022社區(qū)版的實現(xiàn)步驟,具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • C語言、C++內(nèi)存對齊問題詳解

    C語言、C++內(nèi)存對齊問題詳解

    這篇文章主要介紹了C語言、C++內(nèi)存對齊問題詳解,內(nèi)存對齊的問題主要存在于理解struct和union等復合結(jié)構(gòu)在內(nèi)存中的分布,需要的朋友可以參考下
    2014-10-10
  • c語言中exit和return的區(qū)別點總結(jié)

    c語言中exit和return的區(qū)別點總結(jié)

    小編今天給大家整理了關于c語言中exit和return的不同點及相關基礎知識點,有興趣的朋友們可以跟著學習下。
    2021-10-10

最新評論