PPPUC++#11.7

9.7.3 Default Constructors
  • 未初期化オブジェクトはバグのスクツ
    • 駄目だコイツ・・・早く何とかしないと・・・
  • というわけでコンストラクタが出てきたわけです。
    • Date()の例だと、3オペランド渡してやらないとオブジェクトがそもそも生成できないので未初期化になることは「ありえない」
      • コピーコンストラクトはできる
  • string =""とかvector=[] (空っぽ)とか、デフォルトが考えられる場合もありえます
    • vectorの要素としてのオブジェクトの初期化を考えた場合は特に重要.
      • とわいえ static initializeの手法を使えば別に「めんどー」以外の技術的問題はない気もする・・・
  • デフォルトコンストラクタは本来はT()の形だけど、省略可能
  • 組み込み型にも実はデフォルトコンストラクタがある(!)。その場合、値は0
    • int()とかdouble()というのは0のまわりくどーい書き方になる
  • (赤)コンストラクタのつもりで string s2(); とか書くと実は関数定義になる(笑)
  • デフォルトコンストラクタは見栄えの問題以上に重要
    • 特に外から渡された変数が本当に初期化されているかどうかという確証がなくなってしまう
  • はて、Date()はどうする?
    • デフォルトの日付ってなんよ?
  • とまあここでは決め打ち、2001/1/1にしている
      • なんでやねん*1
    • クラスの初期化子に直接書くのもなになので、例のstatic constな方法で関数に区切ります
    • 大抵はインライン化されるので実行時ペナルティはほぼ無いハズ
      • Mr.Sの言とは裏腹に人間が読むときペナルティはだいぶあるとおもうス
  • デフォルトコンストラクタはvalidateチェックは不要(あたりまえ)
  • vectorで楽だよーという話で次
9.7.4 Const menber functions
  • まあこれは当たり前というかなんと言うか・・・
  • メンバ関数の引数がconst指定されている場合、不用意にそのオブジェクトのメンバ関数を呼べない
    • > そのメンバ関数がオブジェクトの内部を変更しないという保証がない
  • のでコンパイラに分かるように「このメンバは書き換えしません」ということをマークしておくのです
    • ret funcname(args) const というようにconstキーワードを後ろに付けるのですね
    • こうするとこの関数内で何か書き換えようとすると怒られる用になって、一貫性が保たれるようになります。
      • これ重要
      • ちなみに更に重要なのは const メンバと非constメンバを分けてオーバーロードすることができる
#include <iostream>
using namespace std;
class A { public:
    void foo()       {cout << "I'm mutable ;)" << endl;}
    void foo() const {cout << "I'm immutable :<" << endl;}
};
main() {
    A mutant;
    const A fixer= A();
    mutant.foo(); // => I'm mutable ;)
     fixer.foo(); // => I'm immutable :<
}
      • ことだと思ってます。これはまだまだ相当先ですが 18章あたりで出てきます。
9.7.5 Members and "helper functions"
  • 最小I/Fとしていくと、「単に便利な関数」は除外していく必要が出てきます。
    • こーゆー関数は独立して(クラス外で)定義すべきです。
  • 何故か?
    • 内部(本体、実身)をいじれる人が減れば減るほど、デバッグに有利だからです
      • Mr.Sの表現が面白い >> Not accessing the representation is important because the usual debug technique is "round up the usual suspects"; まず怪しいのはアリバイのない人達なのだー
    • 数十くらいならまあイイカンジ。50もあったら死ぬでしょ?
  • 50も???アホか??? と思ったでしょキミタチ
    • 数年前にいくつかの商用でつかわれてるDateクラスを調べたことがあってね。。。
      • 調べたのかよ!w
    • するとどうだ! nextSunday()だとか next_workday()だとかのオンパレード
    • まあ50はユーザーの利便性を考えると無茶な数字じゃない。コードの理解や実装やメンテの容易さを考えなければね・・・・
      • 。。。。。。
  • 便利関数を外に弾きだすのには、もうひとつの利点があって、それは内部実装に変更があった場合、内部メソッドだけを直せばイイこと。
  • Date()でいうと現在の year, month, dayの3変数の内部表現から、1900/1/1からの日数、という1変数による内部表現に変えた場合とか。
  • helper関数は convenience functionとか auxilliary functionとかも呼ばれる。
      • 便利関数と補助関数くらい??
  • helperとそうでない単なる関数はどうちがうの?
    • helperは言語仕様上にあるものではなくてあくまで論理的な物(仕様上にあってもおもしろそうだけど)
    • 大抵は引数に補助するクラス(の参照)を取るので、それとわかる
    • もちろん例外も -> yearのみを受け取る閏年判定関数とか
      • 正直それも Dateうければ良いと思うんだけど・・・・

9.8 The Date class

  • Dateクラスの全容が明らかに・・・
      • いや、本当にそのまんまです
    • ちゃっかり >> とか <<まで実装してるけど、詳細は次のI/Oの章で。。。

*1:余談ですが google翻訳でこれ入れるとベタさ加減に少しだけ笑えます