欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++類與對(duì)象的重點(diǎn)知識(shí)點(diǎn)詳細(xì)分析

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

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

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

1、拷貝構(gòu)造

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

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

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

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

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

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

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

特征3需要注意的是:在編譯器生成的默認(rèn)拷貝構(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,此處會(huì)調(diào)用Date類的拷貝構(gòu)造函數(shù)
    // 但Date類并沒有顯式定義拷貝構(gòu)造函數(shù),則編譯器會(huì)給Date類生成一個(gè)默認(rèn)的拷貝構(gòu)
    // 造函數(shù),_t為自定義類型,會(huì)自動(dòng)調(diào)用自己的構(gòu)造函數(shù)完成拷貝
    Date d2(d1);
    return 0;
}

2、賦值運(yùn)算符重載

2.1 運(yùn)算符重載

在學(xué)習(xí)賦值運(yùn)算符重載時(shí),我們先學(xué)習(xí)一下運(yùn)算符重載。

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

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

運(yùn)算符重載有五個(gè)需要注意的點(diǎn):

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

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

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ù)的對(duì)象
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 賦值運(yùn)算符重載

賦值運(yùn)算符重載格式:

  • 參數(shù)類型:const T&,傳遞引用可以提高傳參效率;
  • 返回值類型:T&,返回引用可以提高返回的效率,有返回值目的是為了支持連續(xù)賦值;
  • 檢測(cè)是否自己給自己賦值;
  • 返回*this :要復(fù)合連續(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)//判斷是否自己給自己復(fù)制
        {
            _year = d._year;
            _month = d._month;
            _day = d._day;
        }
        return *this;
    }
private:
    int _year ;
    int _month ;
    int _day ;
};

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

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

3、普通對(duì)象取地址

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

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

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

4、const對(duì)象取地址

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

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

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

二、類和對(duì)象重點(diǎn)知識(shí)點(diǎn)

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)用之后,對(duì)象中已經(jīng)有了一個(gè)初始值,但是不能將其稱為對(duì)對(duì)象中成員變量的初始化,構(gòu)造函數(shù)體中的語句只能將其稱為賦初值,而不能稱作初始化。因?yàn)槌跏蓟荒艹跏蓟淮危鴺?gòu)造函數(shù)體內(nèi)可以多次賦值

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

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

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

初始化列表需要注意的幾點(diǎn):

  • 每個(gè)成員變量在初始化列表中只能出現(xiàn)一次(初始化只能初始化一次);
  • 引用成員變量、const成員變量、自定義類型成員(且該類沒有默認(rèn)構(gòu)造函數(shù)時(shí)) ,這三個(gè)成員變量必須放在初始化列表位置進(jìn)行初始化;
  • 盡量使用初始化列表初始化,因?yàn)椴还苣闶欠袷褂贸跏蓟斜恚瑢?duì)于自定義類型成員變量,一定會(huì)先使用初始化列表初始化。
  • 成員變量在類中聲明次序就是其在初始化列表中的初始化順序,與其在初始化列表中的先后次序無關(guān)。

2、static成員

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

static修飾特征:

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

3、友元函數(shù)

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

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

例如當(dāng)我們實(shí)現(xiàn)運(yùn)算符'>>'和‘<<’的重載時(shí)就使用到了友元函數(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ù)可訪問類的私有和保護(hù)成員,但不是類的成員函數(shù);
  • 友元函數(shù)不能用const修飾;
  • 友元函數(shù)可以在類定義的任何地方聲明,不受類訪問限定符限制;
  • 一個(gè)函數(shù)可以是多個(gè)類的友元函數(shù);
  • 友元函數(shù)的調(diào)用與普通函數(shù)的調(diào)用原理相同。

4、友元類

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

  • 友元關(guān)系是單向的,不具有交換性。
  • 比如上述Time類和Date類,在Time類中聲明Date類為其友元類,那么可以在Date類中直接
  • 訪問Time類的私有成員變量,但想在Time類中訪問Date類中私有的成員變量則不行。
  • 友元關(guān)系不能傳遞
  • 如果C是B的友元, B是A的友元,則不能說明C時(shí)A的友元。
class Time
{
    friend class Date; // 聲明日期類為時(shí)間類的友元類,則在日期類中就直接訪問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)
    {
        // 直接訪問時(shí)間類私有的成員變量
        _t._hour = hour;
        _t._minute = minute;
        _t._second = second;
    }
private:
    int _year;
    int _month;
    int _day;
    Time _t;
};

總結(jié)

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

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

相關(guān)文章

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

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

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

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

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

    C++中CSTRINGLIST用法詳解

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

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

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

    C++友元(Friend)用法實(shí)例簡(jiǎn)介

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

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

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

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

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

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

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

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

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

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

    小編今天給大家整理了關(guān)于c語言中exit和return的不同點(diǎn)及相關(guān)基礎(chǔ)知識(shí)點(diǎn),有興趣的朋友們可以跟著學(xué)習(xí)下。
    2021-10-10

最新評(píng)論