◆ ポインタのアウト引数 |
C++になって参照引数が使えるようになりました。 では、今まで引数にポインタを使っていたような場面を、全て参照にしてしまった方がいいのでしょうか? 例えば、こんな関数があったとします。 void getCurTime(int& nYear, int& nMonth, int& nDay, int& hh, int& mm, int& ss) { CTime time = CTime::GetCurrentTime(); nYear = time.GetYear(); nMonth = time.GetMonth(); nDay = time.GetDay(); hh = time.GetHour(); mm = time.GetMinute(); ss = time.GetSecond(); }現在の日時、時間を返してくれる関数ですね。 しかし、この関数だと、もし現在の『日付だけ』が欲しい場合にも、下のように変数を6つ用意しなければなりません。 void main(){ int nYear, nMonth, nDay, hh, mm, ss; getCurTime(nYear, nMonth, nDay, hh, mm, ss); printf("本日は%0000d年%00d月%00d日です"); // hh, mm, ssは使っていない!! }まぁこれでも問題ない場合も多いのですが(笑)、沢山の使わない変数を用意しなければならないというのは、あまり気分のいいものではありませんね。 そこで、以下のように関数を変えてみてはどうでしょうか。 // ポインタがNULLじゃなければ代入、のマクロ #define SAFE_SET(p, val) (if(p) *p = val) void getCurTime(int* nYear, int* nMonth = NULL, int* nDay = NULL, int* hh = NULL, int* mm = NULL, int* ss = NULL) { CTime time = CTime::GetCurrentTime(); SAFE_SET(nYear, time.GetYear()); SAFE_SET(nMonth, time.GetMonth()); SAFE_SET(nDay, time.GetDay()); SAFE_SET(hh, time.GetHour()); SAFE_SET(mm, time.GetMinute()); SAFE_SET(ss, time.GetSecond()); }こうすることにより、先ほどのmainは次のように書くことができます。 void main(){ int nYear, nMonth, nDay; getCurTime(&nYear, &nMonth, &nDay); printf("本日は%0000d年%00d月%00d日です"); }どうでしょう。 無駄な変数を定義する必要がなく、すっきり感じた方も多いのではないでしょうか。 これも好みの問題になってしまうので、もししっくりこない方は、『こんな方法もある』程度に心にとどめておいてください。 この「必要な場合とそうでない場合がある引数」にポインタを持ってくる方法は、引数にクラス等のサイズが大きめのモノが来る場合、インスタンスそのものをデフォルト引数に使う方法に比べ、メモリの無駄遣いを少なくするという効果もあります。 しかし、あくまでもポインタなので、多用するか否かはプログラマのセンスにかかってくると思います。 大容量時代を迎えた今、「よいプログラム」とは、効率はもちろんのこと、保守に多大に関わる『可読性』も重要なファクターとなってきます。 効率と可読性、一番いいバランスを保てるように、コーディングしていくことに心がけていきましょう。 |