読者です 読者をやめる 読者になる 読者になる

EffectiveC++改訂2版 22項〜28項

Smalltalk勉強会に向けての予習のため休んでいたEffectiveC++改訂2版の勉強の再開。

22項

リファレンス渡しは素晴らしいが、独特の複雑さを伴う。特に悪名高いのは17項で説明したエイリアシングの問題である。

これは身に付いている。

23項

アルバートアインシュタインの言葉

ものごとは最小限度までシンプルにしなさい。ただし限度を超えてはいけない。

22項を理解したプログラマが十字軍になったとき。

リファレンス渡しだけの清らかな世界を熱心に追及するあまり、彼らは決まって致命的な過ちを犯す。存在しないオブジェクトへのリファレンスを渡そうとするのだ。

ローカルオブジェクトへのリファレンスを返す

これはローカルオブジェクトへのポインタを返すのと同じ。もともとリファレンスとポインタは意味的に近い。

リファレンスを返すかオブジェクトを返すかを決めるときは、正しい行いをする方を選ぶのが、あなたの仕事である。その選択をなるべく安く済ませる方法を探す努力は、コンパイラのベンダに任せよう。

24項

一般に適切なデフォルト値を選ぶことができて、しかも採用したいアルゴリズムが1つしかないときは、デフォルトパラメータを使う。そうでなければ関数をオーバーロードする。

デフォルト値の適切さが問われるのだけれど、振り返ると結構いい加減。アルゴリズムが1つというのは守れている。

これは忘却の彼方(汗)のでさっそく試してみる。
charの場合、static_castしないと、std::cout がcharとして表示しようとするため文字化けになるのに時間がかかった。

#include <iostream>
#include <limits>

int main()
{
    std::cout << "char:\t" <<
        static_cast<int>(std::numeric_limits<char>::min()) << "\t" <<
        static_cast<int>(std::numeric_limits<char>::max()) << std::endl;
    std::cout << "short:\t" <<
        std::numeric_limits<short>::min() << "\t" <<
        std::numeric_limits<short>::max() << std::endl;
    std::cout << "int:\t" <<
        std::numeric_limits<int>::min() << "\t" <<
        std::numeric_limits<int>::max() << std::endl;
    std::cout << "long:\t" <<
        std::numeric_limits<long>::min() << "\t" << 
        std::numeric_limits<long>::max() << std::endl;
    std::cout << "long long:\t" <<
        std::numeric_limits<long long>::min() << "\t" <<
        std::numeric_limits<long long>::max() << std::endl;
    std::cout << "float:\t" <<
        std::numeric_limits<float>::min() << "\t" <<
        std::numeric_limits<float>::max() << std::endl;
    std::cout << "double:\t" <<
        std::numeric_limits<double>::min() << "\t" <<
        std::numeric_limits<double>::max() << std::endl;
    std::cout << "long double:\t" <<
        std::numeric_limits<long double>::min() << "\t" <<
        std::numeric_limits<long double>::max() << std::endl;
}
関数オーバーロードを必須のとき
  • デフォルト値として使うのに適当な値がない場合
  • 与えられた入力に依存してアルゴリズムを使い分けなければならない場合。コンストラクタが典型的。

25項

数値型とポインタ型とにオーバロードするのは可能な限り避けること

26項

特になし。

27項

不要なメンバ関数の対処
  • private宣言する
  • 関数定義を書かない

28項

namaspaceを書くとインデントが深くなるなあ。
宣言・定義と実装とで分けるのだろうか。