C++のTIPS

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

C++のTIPS

投稿記事 by beatle » 14年前

あるソースを読んでいて気づいた点など。
  • 構造体をコピーするときは代入演算子を使おう

    CODE:

    struct A a, b; memcpy(&a, &b, sizesof(A));
    とやるのは良くない。なぜなら、Aのコピーコンストラクタが呼び出されないから。代わりに次のように書こう。

    CODE:

    struct A a, b; a = b;
    もしかしたら、Aはなんらかのポインタを持っており、コピーコンストラクタ内で新たに領域をnewして、そこへコピーするような実装かもしれない。
    さらに継承を使っている場合にも問題がある場合がある。memcpyを使ってコピーすると、仮想関数テーブルもコピーされてしまう。
  • クラスの初期化子リストを使おう
    Effective C++にも書かれていることだが、初期化子リストの方がしばしば効率的に初期化できる。
    初期化子リストを使わず、コンストラクタ内で代入する場合、ユーザー定義型のメンバ変数についてはデフォルトコンストラクタが
    呼び出されて初期化された後、代入演算子によって値が代入される。
    組み込み型は初期化されないため、初期化子リストでもコンストラクタ本体での代入でもコストは一緒だが、
    「初期化子リストで全て初期化する」ということに決めておけば、どの変数が未初期化なのかを気にしなくて済む。
    未初期化の変数を使うと「動作未定義の世界への扉が開かれてしまう」のだ。
    ちなみに初期化子リストとは

    CODE:

    constructor() : foo1(bar1), foo2(bar2) {}
    の「: foo1(bar1), foo2(bar2)」の部分のこと。
  • deleteするポインタがnullかどうかチェックしなくてもいい
    標準ライブラリで提供されるdeleteの場合、nullポインタを渡した場合何もしないことになっている。
    つまり、fooというポインタをdeleteする場合

    CODE:

    if (foo != 0) { delete foo; }
    と書くのと

    CODE:

    delete foo;
    と書くのは(実行速度は多少違うかもしれないが)同じ事だ。
    ちなみに、nullポインタを渡しても大丈夫という性質のお陰で、delete済のポインタにnullポインタを設定しておくことは
    2重デリートを防ぐ有効な方法である。
最後に編集したユーザー beatle on 2011年11月28日(月) 08:40 [ 編集 5 回目 ]

コメントはまだありません。