こんばんは。
今までC言語とDXライブラリを用いて、ゲームを作成してきたのですが、
オブジェクト指向の勉強をしてみたいと思い、C++で何かを書こうと思い立ちました。
今回は、ゲームの1要素である「エフェクト」を作ってみようとしました。
エフェクト全体を扱うクラスをmainでnewしたときに(そのコンストラクタで)、
実際のエフェクト(基本エフェクトクラスから派生)をnewし、
そのポインタを全体を扱うクラスのメンバのポインタmlpNowEffect(型は基本エフェクトクラス)に保持します。
この時(保持した瞬間)はそのポインタがしっかりと保持されているのですが、
全体を扱うクラスの別のメンバ関数をmainから呼んだときには、ポインタがNULLになっていて、
正常にその先を呼び出すことができません。
どこでNULLになっているのか、ブレークポイント等を設置して調べてみたのですが、見当がつかず。。。
助言を頂けないでしょうか?
ソースは以下です(要DXライブラリ)。ビルドが通るのは確認しています。
http://www1.axfc.net/uploader/so/2994046.zip
[DLパス]
cppeffect
環境は以下です。
・OS:Windows 8
・開発環境:Visual Studio 2012 Professional
また、C++のクラスの勉強用に書いたソースですので、クラスの構成や名前、機能などに
改良できる点などがあれば、指摘お願いいたします。
派生クラスへのポインタが勝手にNULLになる
Re: 派生クラスへのポインタが勝手にNULLになる
【IEffect.hの抜粋】
引数なしのコンストラクタで、引数ありのコンストラクタを呼んでいますが、これはおそらく意図した動作をしません。
IEffect(0);という記述は、IEffectクラスの一時オブジェクトを作成してすぐに破棄するだけだからです。
同じクラスの別のコンストラクタを使って初期化することはできない(C++11を除く)ので、
以下のように書く必要があります。
#多少冗長なので、mにデフォルト引数をつけるとかエフェクト作成部分を関数化するとか工夫の余地はあります
IEffect(int m) : mMode(m) , mlpNowEffect(NULL) { //初期モード指定版コンストラクタ。
mlpNowEffect = getLpNewEffect(mMode);
}
IEffect() { //コンストラクタ(オーバーロード)。IEffectクラスのインスタンスが生成されたときに呼ばれる
IEffect(0);
}
IEffect(0);という記述は、IEffectクラスの一時オブジェクトを作成してすぐに破棄するだけだからです。
同じクラスの別のコンストラクタを使って初期化することはできない(C++11を除く)ので、
以下のように書く必要があります。
#多少冗長なので、mにデフォルト引数をつけるとかエフェクト作成部分を関数化するとか工夫の余地はあります
Re: 派生クラスへのポインタが勝手にNULLになる
a5ua様、返信ありがとうございます。
なるほど。コンストラクタの中で別の同じクラスのコンストラクタを呼ぶと、
オブジェクトが一時的に生成されて破棄されるだけの動作になってしまうのですね。
疑問が解決しました。
コンストラクタ部分は、
とする(デフォルト引数を指定する)ことで冗長性をカットしました。
このように変更した後、ビルドし、正常に動作することを確認しました。
このトピックは解決とさせていただきます。
しかし、C++の勉強も兼ねているので、そちらの面でのアドバイス等がありましたら、
ぜひご教示ください。
ありがとうございました。
なるほど。コンストラクタの中で別の同じクラスのコンストラクタを呼ぶと、
オブジェクトが一時的に生成されて破棄されるだけの動作になってしまうのですね。
疑問が解決しました。
コンストラクタ部分は、
IEffect(int m=0) : mMode(m) , mlpNowEffect(NULL) { //初期モード指定版コンストラクタ。
mlpNowEffect = getLpNewEffect(mMode);
}
このように変更した後、ビルドし、正常に動作することを確認しました。
このトピックは解決とさせていただきます。
しかし、C++の勉強も兼ねているので、そちらの面でのアドバイス等がありましたら、
ぜひご教示ください。
ありがとうございました。