今日のひらしょー本(20150323):Cp2 - CodeCheck

今日のひらしょー本の目次

http://snoopopo.hatenablog.com/entry/2015/04/27/114854

#ひらしょーさんのソースは、 以下より抜粋

( 02_2DGraphics1\NimotsuKunDot\main.cpp )( 02_2DGraphics1\NimotsuKunBox\main.cpp )( 02_2DGraphics1\NimotsuKunBoxWithTermination\main.cpp )

deleteとdelete[]の判断

まず、delete忘れがあったので注意.それと deleteとdelete[]を間違えてた箇所があった.

deleteとdelete[]の違いは、1.4.6 2種類のdeleteにもある通り. *1

それと、以下のようなソースのとき、

char* stage;
read( &stage, "./stagedata.txt" );

delete[] stage; //←なんで配列ってわかった??
stage = 0;

ポインタ stageData が配列を指したポインタなのか、オブジェクト単体を指したポインタなのかが、 メソッドの中をみるまでわからないというのはどうなの?と思ったけど、

普段はあまり関数の中でnewして外でdeleteするようなことはないらしい.

むしろこれ(deleteかdelete[]かぱっと見でわからない)がよくないからそういう書き方するってことかな、と。

この章ではこのファイル読込処理をクラスの外に書いてるけど、試しにクラスにしてみた.

class FileReader{
public: 
    FileReader( const char* filename );
    ~FileReader(){
        delete[] mStage;
        mStage = 0;
    }

    char* mStage;
};

FileReader::FileReader( const char* filename ){

    ifstream in( filename );
    if ( !in ){
        cout << "stage file could not be read." << endl;
    }else{
        in.seekg( 0, ifstream::end );
        int size = static_cast< int >( in.tellg() );
        in.seekg( 0, ifstream::beg );
        mStage = new char[ size ];
        in.read( mStage, size );
    }
}

↑で書いてたstageをメンバ変数のmStageにしてしまって、 コンストラクタで配列つめて、デストラクタでdelete[]してみた.

初期化

自分のコードが全然初期化をしていないことに気付いた.

明示的に初期化しない場合にどんな値になるのかはよくわからないし、javaでもわかってなかったけど,

基本、初期化しましょう.

・ひらしょーさん

//初期値で埋めとく
for ( int y = 0; y < mHeight; ++y ){
    for ( int x = 0; x < mWidth; ++x ){
        mObjects( x, y ) = OBJ_WALL; //あまった部分は壁
        mGoalFlags( x, y ) = false; //ゴールじゃない
    }
}
mWidth = mHeight = 0; //初期化

なぜ関数にconstがついてないのに呼べてる??【考え中】

ひらしょーさんソースだと、State::draw から呼ばれる State::drawCell というメンバ関数にconstがついていない….

1.4.5 メンバ関数のconst にある通り、

draw() はconstなので、constからconstしか呼べないという理解だったのだが、コンパイルが通る.

・ひらしょーさん

void State::draw() const {
    drawCell( x, y, color );
}
void State::drawCell( int x, int y, unsigned color ){ /*略*/ };

・僕のソース

void Status::draw() const{
    drawCell( x, y, color );
}
void Status::drawCell( const int x, const int y, const unsigned color ) const{ /*略*/ };

↑メンバを変えないので、constつけまくってみたのだけど…;;

僕のソースでメンバ関数のconstをなくしてみると以下のようなエラーが出る.これってconstつけないといけないという意味だと思うから意図してるんだけどな.

error C2662: 'Status::drawCell' : 'const Status' から 'Status &' へ 'this' ポインタを変換できません。

うむ… ここはもう少し調べる必要がありそうだ.

20130324 add --------------------,

→ drawCell() にstaticついてた!!!!!!!!

・ひらしょーさん

class State{
private:
    static void drawCell( int x, int y, unsigned color );
}

つまりjavaと同じと考えていいなら(ぱっと調べた感じは大丈夫そう)

drawCell はメンバ関数じゃなくてクラス関数(クラスのもちもの)ということだ!!

constつける以前に

staticな静的関数からはメンバ(オブジェクトのもちもの)は変更できない.

なのでコンパイルが通ってるようだ.

これをstaticにした理由とかはこの後出てくると思うので、ここでは深追いしない. 単純にユーティリティみたいな機能だからかなと思ってるのだけど.

20150328add,------

ちなみに宣言にstaticついてて、定義にstaticついてないのはわかりづらいなと思ったのだけど、 こんな書き方は、コンパイル通らない*2ので注意.

static void State::drawCell( int x, int y, unsigned color ){~(略)~}

*1:Effective C++ 16頁 対応するnewとdeleteは同じ形のものを使おう にも同じような内容が.

Effective C++ 第3版 (ADDISON-WESLEY PROFESSIONAL COMPUTI)

Effective C++ 第3版 (ADDISON-WESLEY PROFESSIONAL COMPUTI)

*2:「'static' をメンバ関数の定義に使ってはいけません。」ってでた。