C++學(xué)習(xí)筆記二

使用類

  1. 運算符重載

  • 重載后的運算符必須至少有一個操作數(shù)是用戶定義的類型
  • 使用運算符時不能違反原來運算符的句法規(guī)則, 同樣不能修改運算符的優(yōu)先級
  • 不能創(chuàng)建新的運算符, 例如定義operator**()函數(shù)來表示求冪
  • 不能重載以下運算符
  • sizeof : sizeof運算符
  • . : 成員運算符
  • .* : 成員指針運算符
  • :: : 作用域解析運算符
  • ?: : 條件運算符
  • typeid : 一個RTTI運算符
  • const_cast, dynamic_cast, reinterpret_cast, static_cast : 強(qiáng)制類型轉(zhuǎn)換運算符
  • 以下運算符只能通過成員函數(shù)重載
  • = : 賦值運算符
  • () : 函數(shù)調(diào)用運算符
  • [] : 下標(biāo)運算符
    -> : 通過指針訪問類成員的運算符
  • 以下運算符可通過成員函數(shù)或非成員函數(shù)重載


    reloadable_operator.png
  1. 友元

  • 友元有三種:
  • 友元函數(shù)
  • 友元類
  • 友元成員函數(shù)
    通過讓函數(shù)成為類的友元,可以賦予該函數(shù)與類成員函數(shù)相同的訪問權(quán)限
  • 為何需要友元

在為類重載二元運算符時, 常常需要友元
雙目運算符交換兩邊操作數(shù)結(jié)果應(yīng)該是一樣的, 為了滿足兩種用法, 非成員函數(shù)重載運算符為了能夠使用類的私有成員將函數(shù)聲明為類的友元函數(shù)
創(chuàng)建友元函數(shù)的方法如下代碼:

class Point {
    int x;
    int y;
public:
    Point(int xv = 0, int yv = 0): x(xv), y(yv) {}
    Point operator*(int fac) const {
        Point res;
        res.x = x * fac;
        res.y = y * fac;
        return res;
    }
    // 1. 將函數(shù)原型放在類聲明中, 并加上關(guān)鍵字friend
    friend Point operator*(int fac, const Point& p);
    void show() {
        cout << "(" << x << ", " << y << ")\n";
    }
};
// 2. 編寫定義函數(shù), 他不是成員函數(shù)不要加Point::限定
//    另外注意不能在定義中使用friend關(guān)鍵字, 除非為內(nèi)聯(lián)函數(shù)的情況(原型也是定義)
Point operator*(int fac, const Point& p) {
    Point res;
    res.x = p.x * fac;
    res.y = p.y * fac;
    return res;
}
  • 常用的友元: 重載<<運算符

用cout << name 來輸出用戶定義類型
一種實現(xiàn)代碼如下:

// 在類中聲明原型
friend void operator<<(ostream & os, const Point& p);
// 定義
void operator<<(ostream & os, const Point& p) {
    os << "(" << p.x << ", " << p.y << ")\n";
}

另一種更好的實現(xiàn), 適應(yīng)cout << x << y這種用法
代碼如下:

ostream & operator<<(ostream & os, const Point& p) {
    os << "(" << p.x << ", " << p.y << ")\n";
    return os;
}
  1. 類的自動類型轉(zhuǎn)換和強(qiáng)制類型轉(zhuǎn)換

  • C++的類型轉(zhuǎn)換
  • 將一個標(biāo)準(zhǔn)類型變量的值賦給另一種標(biāo)準(zhǔn)類型的變量時, 如果這兩種類型兼容, 則C++自動講這個值轉(zhuǎn)換為接收變量的類型
long a = 22; // type int -> type long
double b = 33; //
int c = 3.14; //
  • C++不自動轉(zhuǎn)換不兼容的類型, 例如:
    int* p = 10;
  • 但是可以使用強(qiáng)制類型轉(zhuǎn)換
    int* p = (int*)10;
  • 將構(gòu)造函數(shù)用作自動類型轉(zhuǎn)換
class ConvInt {
public:
    ConvInt(int x) { m_x = x; }    
private:
    int m_x;
}
ConvInt ci = 10; // 合法
  • explicit關(guān)鍵字用于關(guān)閉這種特性, 但仍可以顯示轉(zhuǎn)換
class ConvInt {
public:
    explicit ConvInt(int x) { m_x = x; }    
private:
    int m_x;
}
ConvInt ci = 10; // 不合法
ConvInt cj = ConvInt(10); // 合法
ConvInt ck = (ConvInt)10; // 合法
  • 注意: 只接收一個參數(shù)的構(gòu)造函數(shù)定義了從參數(shù)類型到類類型的轉(zhuǎn)換
  • 何時使用ConvInt(int)函數(shù)?

如果在聲明中使用了關(guān)鍵字explicit, 則ConvInt(int)將只用于顯示的強(qiáng)制轉(zhuǎn)換, 否則還可以用于以下隱式轉(zhuǎn)換:

  • 將ConvInt對象初始化為int值時
  • 將int值賦給ConvInt對象時
  • 將int值傳遞給接受ConvInt參數(shù)的函數(shù)時
  • 返回值被聲明為ConvInt的函數(shù)試圖返回int值時
  • 在上述任一種情況下,使用可轉(zhuǎn)換為int類型的內(nèi)置類型時
    對以上最后一條而言轉(zhuǎn)換不能出現(xiàn)二義性
  • 轉(zhuǎn)換函數(shù)

轉(zhuǎn)換函數(shù)用于將類類型轉(zhuǎn)換為某種類型
例如有以下語句

ConvInt ci(10);
double dt1 = double(ci);
double dt2 = (double)ci;
double dt3 = ci;

轉(zhuǎn)換函數(shù)應(yīng)滿足以下幾點:

  • 轉(zhuǎn)換函數(shù)必須是類方法
  • 轉(zhuǎn)換函數(shù)不能指定返回類型
  • 轉(zhuǎn)換函數(shù)不能有參數(shù)
    例如, 轉(zhuǎn)換為double類型的原型聲明如下:
    operator double();
  • 程序中不能出現(xiàn)二義性轉(zhuǎn)換, 例如:
class ConvInt {
public:
    ConvInt(int x) { m_x = x; }
    operator int() {
        return m_x;
    }
    operator double() {
        return double(m_x);
    }
private:
    int m_x;
}
ConvInt ci(1);
double dt = ci;  // 合法, 根據(jù)上下文知道使用operator double()轉(zhuǎn)換
cout << ci;      // 不合法, 編譯器會認(rèn)為有二義性而拒絕
cout << int(ci); // 合法
  • 隱式自動轉(zhuǎn)換請謹(jǐn)慎使用, 建議永遠(yuǎn)做顯式轉(zhuǎn)換
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容