Effective C++ 入門 
〜 第一章 CからC++への移行 〜


□ 1項 □ #defineではなく、const と、inlineを使おう
■ 課題

プリプロセッサ宣言は、コンパイラによって取り除かれる。デバッグ時、実数がそのまま入るため、値がどこで設定されているかわからない。

例)#define ASPECT_RATIO 1.653

さらに、次のようなプリプロセッサ宣言はうまく働かない可能性がある。

例) #define max(a, b) ((a) > (b) ? (a) : (b))

たとえば次のように指定した場合。 max(++a, b) 次のように展開されてしまい、2回インクリメントされる

max(++a, b) → ((++a) > (b) ? (++a) : b)

■ 解決

#defineではなく、const と、inlineを使う

例) const double ASPECT_RATIO = 1.653

例) inline int max(int a, int b) { return a > b ? a : b; }

上級者は次のようにすればもっとエレガント

template<class T> inline const T& max(const T& a, const T& b) { return a > b ? a: b; }

■ 補足

EffectiveC++には記載されていないが、inline を virtual 関数に適用してはいけない。もっとも効率のよいinlineの使い方はマクロ代わりに使うこと。inline化するかどうかは、コンパイラの判断にまかされており、inline 化されるとは限らない。特にローカル変数をもつinline関数は、inline展開されないことが多い。inline のパフォーマンスに与える影響は、『EfficientC++』に詳しい。
□ 2項 □ <stdio.h>ではなく、<iostream>を使おう
■ 課題

stdioライブラリは、型安全性と、拡張性を欠いている。型指定において、ポインタのあるなしを考慮しなければならない。

■ 解決

C++でプログラミングすることとは、そういうものだと思ってください。詳細は、『EffectiveC++』を参照。

■ 補足

・ iostreamなど stdライブラリは、stdc++ライブラリにある。
・ iostreamは、std名前空間にあるので、std::cout と書く必要がある。面倒なときは、using namespace std; と名前空間の使用を明示的に指定すれば、cout をそのまま使える
□ 3項 □ malloc/free ではなく、new/delete を使おう
■ 課題

mallocで確保したメモリは、初期化の仕方を指定できない。また、開放後の処理を指定できないので使用すべきでない

例)
string* stringArray = static_cast<string*>(malloc(10*sizeof(string));
free(stringArray);


■ 解決

new / deleteを使う

これらを使用すべき理由の詳細は、『EffectiveC++』を参照

例)
string* stringArray = new string[10];
delete [] stringArray;


■ 補足

・ malloc で確保されたメモリを delete で開放してはいけない
・ new で確保されたメモリを free で開放してはいけない

そのような使い方をした場合の振る舞いは不定になる。

・ string* str = new string で確保したメモリは、delete str で開放すること
・ string* stringArray = new string[10] で確保したメモリは、delete [] stringArrayで開放すること。

delete stringArray もしくは、delete [] str とした場合の振る舞いは不定になる。
□ 4項 □ コメントはC++形式で
■ 課題

次のようなコメントはコンパイルエラーになる。

例)
if ( a > b ) {
/* int temp =a; /* aとb を交換する */
a = b;
b = temp;
*/
}

■ 解決

C++形式でコメントを書くようにすれば、問題解決

例)
if ( a> b ) {
// int temp = a; // aとBを交換する
 // a = b;
// a = temp;
}

■ 補足

・ プリプロセッサでのコメントの使用は注意が必要。#define TEST 5 // test is 5 とすると、TESTが "5 // test is 5" と展開される場合がある

Copyright(C) 2005 Yoshinori Oota All rights reserved.

本ホームページのリンクは自由です。複製、転載される場合は、必ず著者までご連絡をください。