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

Natural Software

KinectなどのDepthセンサーを中心に活動しています

危なっかしいなぁ〜と思うコード

C++

最近 C# と平行して、過去の資産を生かすために C++ でかれたコードを CLI でラップして C# から呼ぶことをよくやるんだけど、そのときの C++ のコードを見ていて危なっかしいなぁ〜と思う時を列挙しとく。

例外を投げるときにが例外クラス以外を投げる

整数を投げられると、受け取るほうが困ります><
困ったときは std::runtime_error を投げときゃいいんじゃないですか??



裸のポインタに動的メモリ確保してる

よくあるのがこんなの
例外とかで解放忘れたらこまるじゃん><

unsigned char* buffer = new unsigned char[64];

vector とか使っとこうよ

std::vector<unsigned char> buffer( 64 );

裸のハンドルにリソースを確保してる・Windows のみ

これも同じく、解放できなかったらどうすんのさ。

HANDLE hFile = ::CreateFile( ... );

ごにょごにょ

::CloseHandle( hFile );

shared_ptr で管理して>

HANDLE hFile = ::CreateFile( ... );
shared_ptr<void> handle = shared_ptr<void>( hFile, &::CloseHandle )

ごにょごにょ

戻り値がポインタ

呼び出し先か呼び出し元かとっちが解放すればいいかわからないので、リークの可能性があってドキドキがとまりません。。。


Windows API のリソースとか返された日にゃもうたまりません><


shared_ptr とか使いませう。



クラスを引数で渡すときに実体で渡してる

実体で渡すとコピーが発生する上に、ポインタを持った自作クラスなんぞ実体で渡されたら、もうドキドキがとまりません。。。


引数にするときは const の参照で渡してください><

void func( string str ) 
{
   ...
}

ではなく

void func( const string& str ) 
{
   ...
}

で渡してください



ディープコピーを考えてない

メンバ変数にポインタを持ってるのに、コピーコンストラクタと代入演算子がない。


これと引数実体渡しとでコンボすると死にますね。。。


const がない

constメンバ関数は重要 - Faith and Brave - C++で遊ぼう


ちょっと前に盛り上がってたけど、const は重要でしょ。


神経質なくらいに const にはこだわります。



ちょっと横道

前に組み込みの C で関数の引数に const をつけたら

  • const つけたら ROM に書かれるだろ!!」

と言われた。


const 引数が ROM に書かれるなら、 ROM ライタいらんだろ! と今なら言えるけど、当時純情なボクはそんなことも言えず、素直に従って const を取ったのがいい思い出です。


#そんなことを言った本人は C++ カンペキと言ってたらしい。。。


とりあえずこんなもんか

C++ って難しいけど、ちゃんと使えれば性能も出るし、リークも自分で作ったところに限って vector と shared_ptr を使えば 0 になると思ってる。
ソースって正直で、書いた人がどんな人か大体わかるよね。