C++ Primer5 第七章課後題 練習筆記

關於class和struct

唯一區別:默認訪問權限不同。類可以在它的第一個訪問說明符之前,定義成員,對這種成員的訪問依賴於類的定義方式。對於struct關鍵字,定義在第一個訪問說明符之前的成員是public的,class則相反。

關於默認的拷貝和賦值

含有指針數據成員的類一般不宜使用默認的拷貝和賦值操作,如果類的數據成員都是內置類型,則不受干擾。

Screen類練習

#include<iostream>
#include<string>
using namespace std;

class Screen
{
private:
    unsigned height = 0, width = 0;
    unsigned cursor = 0;
    string contents;
public:
    Screen() = default;     //默認構造函數
    Screen(unsigned ht, unsigned wd) : height(ht), width(wd),
        contents(ht * wd, ' ') { }
    Screen(unsigned ht, unsigned wd, char c)
        : height(ht), width(wd), contents(ht * wd, c) { }
public:
    Screen& move(unsigned r, unsigned c)
    {
        cursor = r * width + c;
        return *this;
    }
    Screen& set(char ch)
    {
        contents[ cursor ] = ch;
        return *this;
    }
    Screen& set(unsigned r, unsigned c, char ch)
    {
        contents[ r * width + c] = ch;
        return *this;
    }
    Screen& display()
    {
        cout << contents;
        return *this;
    }
};

int main()
{
    Screen myScreen(5, 5, 'X');
    myScreen.move(4,0).set("#").display();
    cout << "\n";
    myScreen.display();
    cout << "\n";
    return 0;
}

move、set和display函數的返回類型是Screen&,返回值是引用,表明函數返回的是對象本身,一系列操作在同一個對象上執行;函數的返回值如果不是引用,表明函數返回的是對象的副本,則上述各函數只返回一個臨時副本,不會改變myScreen的值。

關於不完全類型

不完全類型:聲明未定義。我們可以定義指向不完全類型的指針,但是不能創建不完全類型的對象。

關於類成員聲明的名字查找和成員定義中名字的查找

typedef string Type;        //聲明類型別名Type表示string
Type initVal();             //聲明函數initVal,返回類型是Type
class Exercise{             //定義一個新類Exercise
public:
    typedef double Type;    //在內層作用域重新聲明類型別名Type表示double
    Type setVal(Type);      //聲明函數setVal,參數和返回值的類型都是Type
    Type iniVal();          //在內層作用域重新聲明函數initVal,返回類型是Type
private:
    int val;                //聲明私有數據成員
};
//定義函數setVal,此時的Type顯然是外層作用域的
Type Exercise::setVal(Type parm){ //形參Type用的是類內定義的別名,double
    val = parm + initVal();     //此時使用的是類內的initVal函數
    return val;
}
//上述程序存在問題,返回值類型不匹配
//修改
Exercise::Type Exercise::setVal(Type parm){ //形參Type用的是類內定義的別名,double
    val = parm + initVal();     //此時使用的是類內的initVal函數
    return val;
}

關於使用構造函數初始值列表時成員的初始化順序

初始化順序只與數據成員在類中出現的次序有關,而與初始值列表的順序無關。

struct X{
    X (int i, int j): base(i), rem(base % j) { }
    int rem,base;  //錯誤,應該改爲  int base,rem;
}

提供cin作爲接受istream&參數的構造函數的默認實參,構造函數聲明

Sales_data(std::istream &is=std::cin) { is >> *this; }

關於聚合類

聚合類使得用戶可以直接訪問其成員,並且具有特殊的初始化語法形式。

條件:(1)所有成員都是public(2)沒有定義任何構造函數(3)沒有類內初始值(4)沒有基類,也沒有virtual函

constexpr函數只能包含return語句,不允許執行其他任務。

聚合類即是字面值常量類

什麼是類的靜態成員?它有何優點?靜態成員與普通成員有何區別?

靜態成員是指聲明語句之前帶有關鍵字static的類成員,靜態成員不是任意單獨對象的組成部分,而是由該類的全體對象所共享。

靜態成員的優點包括:作用域位於類的範圍之內,避免與其他類的成員或者全局作用域的名字起衝突;可以是私有成員,而全局對象不可以;通過閱讀程序可以非常容易的看出靜態成員與特定類關聯,使得程序的含義清晰明瞭。

靜態成員和普通成員的區別主要體現在普通成員與類的對象關聯,是某個具體對象的組成部分;而靜態成員不從屬於任何具體的對象,它由該類的所有對象共享。還有,靜態成員可以作爲默認實參,而普通數據成員不能作爲默認實參。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章