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

C++ primer類的基礎(chǔ)精講

 更新時間:2022年07月01日 10:24:15   作者:撲街男孩  
C++類,是指系統(tǒng)在第一次在程序中遇到一個類時為這個類建立它的所有類變量的拷貝 - 這個類的所有實例共享它的類變量

定義抽象數(shù)據(jù)類型

初探this和

struct Sales_data
{
    string isbn(){return bookNo;}
    Sales_data & combine(const Sales_data&);
    double avg_price() const;
    string bookNo;
    unsigned units_sold=0;
    double revenue=0;
};
Sales_data total;

引入this

對于isbn成員函數(shù)的調(diào)用: total.isbn();

當(dāng)我們調(diào)用成員函數(shù)時,實則上是在替某個對象調(diào)用它。在上面的調(diào)用中,當(dāng)isbn返回bookNo時,實際上隱式地返回total.bookNo.

成員函數(shù)通過一個名為this的額外隱式參數(shù)來訪問調(diào)用它的那個對象。當(dāng)我們調(diào)用一個成員函數(shù)時,用請求該函數(shù)的對象地址初始化this。例如,如果調(diào)用total.isbn(),編譯器負責(zé)把total的地址傳遞給isbn的隱式形參this,可以等價認為編譯器將該調(diào)用重寫成Sales_data::isbn(&total),調(diào)用Sales_data時的isbn成員時傳入了total的地址。

在成員函數(shù)內(nèi)部,我們可以直接使用調(diào)用該函數(shù)的對象的成員,而無須通過成員訪問運算符來做到這一點,因為this所指的正是這個對象。任何對類成員的直接訪問都被看做this的隱式調(diào)用,例如,isbn在使用bookNo時,隱式地使用this指向的成員,就如同this->bookNo一樣。

構(gòu)造函數(shù)

定義:類通過一個或幾個特殊的成員函數(shù)來控制其對象的初始化,這些函數(shù)叫做構(gòu)造函數(shù)。

無論何時,只要類的對象被創(chuàng)建,就會執(zhí)行構(gòu)造函數(shù)。

構(gòu)造函數(shù)的名字和類名一樣,構(gòu)造函數(shù)沒有返回類型,一個類可以擁有多個構(gòu)造函數(shù),但每個構(gòu)造函數(shù)之間必須在參數(shù)數(shù)量或參數(shù)類型上存在不同。且構(gòu)造函數(shù)不能被聲明成const。

當(dāng)一個類沒有定義任何構(gòu)造函數(shù)時,編譯器會給類自動添加一個默認構(gòu)造函數(shù),該構(gòu)造函數(shù)無須任何實參對對象進行初始化。

對前面的Sales_data類進行編寫構(gòu)造函數(shù)

struct Sales_data
{
    Sales_data()=default;
    Sales_data(const string &s):bookNo(s)()
    Sales_data(const string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n){}
    Sales_data(istream &)
    string isbn() const{return bookNo;}
    Sales_data &combine(const Sales_data&);
    double avg_price() const;
    string bookNo;
    unsigned units_sold=0;
    double revenue=0.0;
}

(1)=default的含義

如果需要默認構(gòu)造函數(shù)起作用,那么可以在參數(shù)列表后面寫上=default來要求編譯器生成默認構(gòu)造函數(shù)。

(2)構(gòu)造函數(shù)初始值列表

Sales_data(const string &s):bookNo(s)()
Sales_data(const string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n){}

上面出現(xiàn)了兩個新的構(gòu)造函數(shù)的寫法,該部分稱為構(gòu)造函數(shù)初始值列表。

負責(zé)為新創(chuàng)建的對象的一個或幾個數(shù)據(jù)成員賦初值。構(gòu)造函數(shù)初始值是成員名字的一個列表,每個名字后面緊跟括號括起來的成員初始值。

當(dāng)某個數(shù)據(jù)成員被構(gòu)造函數(shù)初始值列表忽略時,他將以合成默認構(gòu)造函數(shù)相同的方式隱式初始化。所以,第一個構(gòu)造函數(shù)等價于:

Sales_data(const string &s):bookNo(s),units_sold(0),revenue(0)();

訪問控制和封裝

訪問控制符public和private

定義在public說明符之后的成員在整個程序可被訪問。

定義在private說明符之后的成員可以被類的成員函數(shù)訪問,但是不能被使用該類的代碼訪問。

Sales_data類的新形式

class Sales_data
{
public:
    Sales_data()=default;
    Sales_data(const string &s):bookNo(s)()
    Sales_data(const string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n){}
    Sales_data(istream &)
    string isbn() const{return bookNo;}
    Sales_data &combine(const Sales_data&);
private:
    double avg_price() const;
    string bookNo;
    unsigned units_sold=0;
    double revenue=0.0;
}

友元

類允許其他類或者函數(shù)訪問他的非公有成員,方法是令其他類或者函數(shù)成為他的友元。如果一個類想把一個函數(shù)作為他的友元,只需要增加一個friend關(guān)鍵字開始的函數(shù)聲明語句即可

class Sales_data
{
    friend Sales_data add(const Sales_data &,const Sales_data&);
    friend istream &read(istream&,Sales_data&);
    friend ostream &print(ostream&,const Sales_data&)
public:
    Sales_data()=default;
    Sales_data(const string &s):bookNo(s)()
    Sales_data(const string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n){}
    Sales_data(istream &)
    string isbn() const{return bookNo;}
    Sales_data &combine(const Sales_data&);
private:
    double avg_price() const;
    string bookNo;
    unsigned units_sold=0;
    double revenue=0.0;
}

友元的聲明只能出現(xiàn)在類定義的內(nèi)部。友元不是類的成員,也不受他所在區(qū)域訪問控制級別的約束。

類的其他特性

可變數(shù)據(jù)成員

在一個const成員函數(shù)中,若希望修改類的某個數(shù)據(jù)成員,可以通過在變量的聲明中加入mutable關(guān)鍵字實現(xiàn)

class screen{
public:
        void some_menmber() const;
private:
        mutable size_t access_ctr
};
void screen::some_member() const
{
    ++access_ctr
}

返回*this的成員函數(shù)

inline Screen &Screen::set(char c)
{
    contents[cursor]=c;
    return *this;
}
inline Screen &Screen::set(pos r,pos col,char ch)
{
    contents[r*width+col]=ch;
    return *this;
}
inline Screen &Screen::move(pos r,pos c)
{
    pos row=r*width;
    cursor=row+c;
    return *this;
}

move和set一樣,返回的值是對對象的引用。

myScreen.move(4,0).set('#');

等同于

myScreen.move(4.0);

myScreen.set('#');

假如我們定義的返回類型不是引用,則move的返回值將是*this的副本,因此調(diào)用set只能改變臨時副本,不能改變myScreen的值

友元類

例如,window_mgr類的某些成員需要訪問screen類的內(nèi)部數(shù)據(jù),例如window_mgr的clear函數(shù)將一個指定的screen類的內(nèi)容設(shè)置為空白。

class Screen{
//window_mgr的成員可以訪問Screen類的私有部分
friend class Window_mgr
//Screen類剩余部分
}
class Window_mgr{
public:
    using ScreenIndex=std::vector<Screen>::size_type
    void clear(ScreenIndex);
private:
    std::vector<Screen> screens{Screen(24,80,' ')}
};
void Window_mgr::clear(ScreenIndex)
{
    Screen &s=screen[i];
    s.contens=string(s.height*swidth,' ')
}

構(gòu)造函數(shù)再探

構(gòu)造函數(shù)初始值列表

(1)構(gòu)造函數(shù)的初始值有時必不可少

如果成員是const或者是引用的話,必須將其初始化

class ConstRef
{
public:
    ConstRef(int ii);
private:
    int i;
    const int ci;
    int &ri;
};

成員ci和ri必須被初始化,如果沒有為他們提供構(gòu)造函數(shù)初始值的話將引發(fā)錯誤。正確形式應(yīng)該是: ConstRef::ConstRef(int ii):i(ii),ci(ii),ri(i){};

如果成員是const,引用,或者屬于某種未提供默認構(gòu)造函數(shù)的類類型,我們必須通過構(gòu)造函數(shù)初始值列表為這些成員提供初值。

(2)成員初始化順序

成員初始化的順序與他們在類定義中的出現(xiàn)順序一致。一般來說初始化的順序沒什么特別要求,不過如果一個成員是用另一個成員來初始化的,那么著兩個成員的初始化順序就關(guān)鍵了。

例如

class X
{
    int i;
    int j;
public:
    X(int val):j(val),i(j){}
};

而編譯器實際上是先初始化i,在初始化j,而初始化i的時候發(fā)現(xiàn)j沒有值,所以上述構(gòu)造函數(shù)會發(fā)生錯誤。

默認構(gòu)造函數(shù)的作用

當(dāng)對象被默認初始化或值初始化時自動執(zhí)行默認構(gòu)造函數(shù)。

默認初始化在以下情況下發(fā)生:

(1)當(dāng)我們在塊作用域內(nèi)不適用任何初始值定義一個非靜態(tài)變量或數(shù)組時。

(2)當(dāng)一個類本身含有類類型的成員且使用合成的默認構(gòu)造函數(shù)時

(3)當(dāng)類類型的成員沒有在構(gòu)造函數(shù)初始值列表中顯示地初始化時

值初始化在以下情況發(fā)生:

(1)在數(shù)組初始化的過程中如果我們提供的初始值數(shù)量少于數(shù)組的大小時

(2)當(dāng)我們不適用初始值定義一個局部靜態(tài)變量

使用默認構(gòu)造函數(shù)

下面的obj的聲明可以正常通過

Sales_data obj();//正確,定義了一個函數(shù)而非對象
if(obj.isbn()==primer_5th_ed.isbn())//錯誤:obj是一個函數(shù)

但當(dāng)我們試圖使用obj時,編譯器將報錯,提示我們不能使對函數(shù)使用成員訪問運算符。因為obj的實際含義是一個不接受任何參數(shù)的函數(shù)并且其返回值是Sales_data類型的對象。

如果想定義一個使用默認構(gòu)造函數(shù)進行初始化的對象,正確方法是去掉對象名之后的空括號對。

Sales_data obj;

聚合類

滿足一下條件的類是聚合類:

(1)所有成員都是public的

(2)沒有定義任何構(gòu)造函數(shù)

(3)沒有類內(nèi)初始值

(4)沒有基類,也沒有虛函數(shù)

例:

struct Data
{
    int val;
    string s;
};

類的靜態(tài)成員

class Account
{
public:
    void calculate(){amount+=amount*interestRate;}
    static double rate(){return interestRate;}
    static void rate(double);
private:
    string owner;
    double amount;
    static double interestRate;
    static double initRate();
}

類的靜態(tài)成員存在于任何對象之外,對象中不包含任何與靜態(tài)數(shù)據(jù)成員有關(guān)的數(shù)據(jù),因此,每個Account對象將包含兩個數(shù)據(jù)成員:owner和amout。只存在一個interestRate對象而且他被所有account對象共享。

靜態(tài)成員函數(shù)也不與任何對象綁定在一個,他們不包含this指針。作為結(jié)果,靜態(tài)成員函數(shù)不能聲明成const的,而且我們也不能在static函數(shù)體內(nèi)使用this指針。

到此這篇關(guān)于C++ primer類的基礎(chǔ)精講的文章就介紹到這了,更多相關(guān)C++類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言實現(xiàn)哈希搜索算法及原理詳解

    C語言實現(xiàn)哈希搜索算法及原理詳解

    本文主要介紹了C語言實現(xiàn)哈希搜索算法及原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Qt帶參數(shù)的信號和槽函數(shù)舉例詳解

    Qt帶參數(shù)的信號和槽函數(shù)舉例詳解

    信號槽的設(shè)計旨在實現(xiàn)控件和處理邏輯的解耦合,但在實際開發(fā)中,一對一的關(guān)系更為常見,這篇文章主要介紹了Qt帶參數(shù)的信號和槽函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2025-03-03
  • C語言三個函數(shù)的模擬實現(xiàn)詳解

    C語言三個函數(shù)的模擬實現(xiàn)詳解

    這篇文章主要為大家詳細介紹了C語言三個函數(shù)的模擬實現(xiàn),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C++11 call_once 和 once_flag的使用與區(qū)別

    C++11 call_once 和 once_flag的使用與區(qū)別

    本文主要介紹了C++11 call_once 和 once_flag的使用與區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • C語言實現(xiàn)輸出平均成績最高學(xué)生的信息

    C語言實現(xiàn)輸出平均成績最高學(xué)生的信息

    這篇文章主要介紹利用C語言實現(xiàn)輸出平均成績最高學(xué)生的信息,文章舉例說明并附有詳細代碼,需要的朋友可以參考一下
    2021-10-10
  • 數(shù)組中求第K大數(shù)的實現(xiàn)方法

    數(shù)組中求第K大數(shù)的實現(xiàn)方法

    本篇文章是對數(shù)組中求第K大數(shù)的實現(xiàn)方法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • 詳解C語言中的字符串拼接(堆與棧)

    詳解C語言中的字符串拼接(堆與棧)

    這篇文章主要介紹了C語言中字符串拼接(堆與棧)的相關(guān)資料,文中通過一段示例代碼詳細介紹了關(guān)于C語言中的字符串拼接問題,有需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-01-01
  • 詳解C++中mutable的用法

    詳解C++中mutable的用法

    這篇文章主要介紹了詳解C++中mutable的用法,幫助大家更好的理解和學(xué)習(xí)C++,感興趣的朋友可以了解下
    2020-08-08
  • C語言中判斷int,long型等變量是否賦值的方法詳解

    C語言中判斷int,long型等變量是否賦值的方法詳解

    聲明了int ,long型等局部變量,在利用一些方法給這些變量賦值之后,想判斷這些變量是不是真的被賦初值了,怎么辦
    2013-07-07
  • C++中queue容器的具體使用

    C++中queue容器的具體使用

    本文主要介紹了C++中queue容器的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03

最新評論