p539〜p564まで

昨日はなんだかんだで遊んでしまった。反省。しかし今日はなぜかやる気がでない。

参照を返す関数

・privateメンバの参照を返す関数でprivateメンバの参照を得てほしくないときは、
 そのメンバをあるクラスにしてラッピングするといいかもしれない。

こんなことをするとまずい。

const int & Hoge(const int& n)
{
  return n;
}

const int& ref = Hoge(3);

この3を格納する一時オブジェクトはこの式が評価された時点で破棄されるので、ダングリングリファレンスとなってしまう。

代入演算子

・=演算子結合法則はa=b=1;の場合、a=(b=1);。右から順に処理される。(認識が甘い!)
・後置++ or --は代入演算を行えない。特殊な代入式である。
・実体を参照する値のことを左辺値(lvalue)、それ以外の値のことを右辺値(rvalue)と呼ぶ。
・Cでは代入式の演算結果はその左辺値を右辺値へと変換した値になる。

演算子オーバーロード

・分子(numerator), 分母(denominator)。(だって知らないんだもん!)
・キャスト演算子オーバーロード可能。戻り値はいらない。operator T();といった定義になる。
・キャスト演算子オーバーロードするとキャストが必要となる状況で自動的にキャストしてくれる。
・単項演算子二項演算子の区別は引数があるかないか。
・前置++,-- or 後置++,--の区別は引数があるかどうか。
・クラスが右項に来る場合はクラス外で演算子オーバーロードする。
・クラス外での演算子オーバーロードはそのクラスのフレンド関数にしておくと便利。

以下は演算子オーバーロードの例。
前提としてHogeクラスを定義しておく。

class Hoge
{
public:
  Hoge(int a) { m_int = a; }

private:
  m_int;
};

前置++,-- or 後置++,--の実装は以下のとおり。

// 前置インクリメント
Hoge& operator ++()
{
  m_int += 1;
  return *this;
}

// 後置インクリメント
Hoge operator ++(int)
{
  Hoge ret = *this; // 後置は++する前の値を返さなければならない。
  m_int += 1;
  return ret;
}

クラスが右項に来る場合の演算子オーバーロードは以下。

// これはクラス外で普通に演算子をオーバーロードしてるだけ。
Hoge operator *(int lope, const Hoge& rope)
{
 return Hoge(lope * rope.m_int);
}
/*
 ちなみに、Hog::operator*(const Hoge&)を定義する代わりに
 operator*(const Hoge&, const Hoge&)を定義して利用することもできる。
 この場合、Hoge a,b; a*b;とした場合、メンバ関数が定義されていればそちらが優先される。
*/

暗黙のキャストの抑制

・コンストラクタにexplicitをつけると暗黙の型キャストが行われなくなる。
・引数が1つになる可能性のあるコンストラクタにはとりあえずexplicitをつけておくと吉。
・コピーコンストラクタにはexplicitはつけない。

explicitはどういう場合につければいいかってのをいちいち考えるのがめんどくさいかったので、いい指針ができてよかったかもしれん。

C++のキャスト

・const_castはvolatileを着脱する場合にも使われる。

腹が減ったので昨日作ったカレーを食う。