はじめに
C/C++を学び始めて一年にも満たない専門学生です。
Effective C++を読んだ記録を残すために細かくわかりやすくまとめていきます。
記事を書くのは初めてなので文章がおかしいところが多いです。
コードのことに触れている2項から書いていこうと思います。
#define
#defineは文字列の置換を行うマクロです。
置換されてからコンパイルされます。
#define MAX_A 100+20
#define Square(b) (b*b)
void Func()
{
//MAX_Aが100に置換される
int a = MAX_A;
//Square(4)が(4*4)に置換される
int b = Square(4);
}
#defineを使うことによる問題
#defineは些細なミスや使われ方によって意図しない動作をすることがあります。
例1
#define MAX_A 100+20
void Func()
{
//120*5でなく100+20*5
int hp = MAX_A * 5;
}
このようなコードの時、
掛け算から先に行われるので
aは
- 期待値 120 * 5 = 600
- 計算結果 100 + 20 * 5 = 200
となり期待値とは異なる値になります。
例2
#define Square(b) (b*b)
void Func()
{
int value;
int b = Square(++value);
}
このようなコードの時、
(++value * ++value)と置換されるので二回インクリメントされます。
例3
#defineでマクロを定義すると#undefをしない限りソースの中では使うことができるので「privateな#define」がなく、カプセル化できないです。
class Class
{
private:
#define MAX_A 100 + 20
}
void Func()
{
int a = MAX_A;//エラーが出ないのでカプセル化できていない
}
※まずこんなコードを書くのは間違っていますが...
解決策
const,enum,inlineを使おう
例1
const,enumで定数を宣言することによって解決することができる。
( )をつけることによっても解決できますが、( )をつけることに注意していてもミスする可能性はあるので使わなければ注意する必要もミスをすることもありません。
#define MAX_A (100 + 20)
const
//MAX_Aは定数
const int MAX_A = 100 + 20;
void Func()
{
int a = MAX_A * 5;
}
enum
enumはintとして扱うことが可能なので下のように使うことができます。
これを「enumハック」といいます。
//MAX_Aは定数
enum {MAX_A = 100 + 20};
void Func()
{
int a = MAX_A * 5;
}
例2
inlineを使うと解決できます。
Effective C++ではtemplateを使うことによってどんな型でも使えるようにしています。
inline
inlineは処理を高速化するための修飾子です。
inlineをつけた関数はインライン関数と呼ばれ、関数の呼び出し部分がインライン関数の内容に置換されて処理が高速化されます。
inline int Square(int b)
{
return b*b;
}
void Func()
{
int b = Square(++value);
}
例3
これでカプセル化できます。
class Class
{
private:
//staticでインスタンスを一つにする
static const int MAX_A = 100 + 20;
}