このようなクラスがあります。
class CBase{
(変数省略)
public:
virtual void Function() = 0;
}
class CChild : public CBase{
(変数省略)
public:
void Function();
}
class CParent{
public:
CChild *p;
(その他変数省略)
void Func2();
}
void CParent::Func2()
{
// forループ(i)
p[i].Function();
}
あらかじめWin32ConsoleAplliでクラス[CChild]の配列データを組んで、バイナリで出力したファイルをリソースとして組み込み
Win32Aplliで
FindResource > LoadResource > LockResource
で先頭ポインタを、[CParent]の[CChild]型ポインタ[p]で受け取り、その[CChild]配列データを[CParent]内で扱うのですが
[p]における[CChild][CBase]の変数はちゃんとデータも入っていて機能するのですが
void CParent::Func2() 内の p[i].Function();
が、デバッグで確かめたところNULLになっていて触れると強制終了してしまいます。
Func2のほかでも、[p]における関数は全てNULLになっており機能しません。
ConsoleAplli側でデバッグしたところ、関数にはNULLじゃない数値が格納されていました。
こういった関数の実行はムリなのでしょうか。
それとも実行の仕方がまずいのでしょうか。
どうかご助力お願いいたします <(_ _*)>
VC++の実装の場合,CBaseは仮想関数を含みますから,
CBaseは「仮想関数テーブルへのポインタ」という暗黙のメンバを持っています。
#大抵のC++実装はそうなっているはず。
CChild::Functionは仮想関数ですから,
p[i].Function()の解決は仮想関数テーブルを経由します。
当然,予期した場所に仮想関数テーブルがなければ未定義動作でしょうね。
というわけで,方法を一から変更する必要がありそうです。
まず,CChildは内部のデータを入出力できるようにして,それをリソースに蓄えます。
そして,そのデータを読み込んでCChildの配列を生成することで,
CParentを復元する,というのが安全な方法です。
読み込んだデータ量によって、ポインタ[p]にnewでメモリ確保し
そこにリソースデータをコピーすることで解決いたしました。
YuOさん、ありがとうございます。