1

仮想クラスを使用して、あるクラスから別のクラスのメソッドを呼び出そうとしています。仮想クラスをインスタンス化するいくつかの方法を試しましたが、常にエラーが発生します。何が間違っていますか? これらは 3 つのコード部分です。

仮想クラス SimData.h を使用しようとしています:

#ifndef SIMDATA_H_
#define SIMDATA_H_

class SimData
{
public:
virtual void onSimUpdate(int id)=0;
};

#endif /* SIMDATA_H_ */

maintask.h から関数を呼び出すには

...
class maintask : public SimData
{
public:
     virtual void onSimUpdate(int id);
...

別のクラスで Select.cpp

.....
SimData* dat;

dat->onSimUpdate(value1); --->HERE IS THE ERROR THAT IT IS NOT INITIALIZED
.....

Select.cpp ファイルで抽象クラスを正しく呼び出す方法を知っていますか?

ありがとうございました。

4

3 に答える 3

6

へのポインタがありますSimData。インスタンスを指すようにする必要があります。例えば、

SimData* dat;
maintask m;
dat = &m; // dat now points to m
dat->onSimUpdate(value1); // OK now

を呼び出すと、に代入できるnew maintask()へのポインタが生成されることに注意してください。動的割り当てとポインターによるポリモーフィズムは 2 つの別個の問題であるため、この例は使用していません。さらに、生のed ポインターを扱うことには危険が伴います。maintaskdatnew

以下は、より現実的な例ですが、動的割り当てもポインターもありません。

void foo(SimData& data, int x) { dat.onSimUpdate(x); }

maintask m;
foo(m, 42);
于 2013-11-05T16:29:57.427 に答える
4
SimData* dat;
dat->onSimUpdate(value1);

上記のコードでは、仮想関数とは何の関係もありません。すべては、ポインターを初期化していないという事実に関係しています (これは決して着陸しないことを指しています)。それを何かに割り当てる必要があります:

SimData* dat = new maintask;
dat->onSimUpdate(value1); // this will now work
// NOTE:  you need to delete dat at some point!
于 2013-11-05T16:31:07.277 に答える
1

生のポインターの代わりに、スマート ポインターを使用します。

std::unique_ptr<SimData> dat(new maintask());
dat->onSimUpdate(value1);
// deletion will happen automatically; no need to do it yourself

利用可能な場合は優先std::make_uniqueします(ない場合は調べてください)。

生のポインターには、スマート ポインターとは異なり、次の 3 つの大きな問題があります。

  • それらは手動のメモリ管理を必要とし、保守や読み取りが困難なコードにつながります。
  • newとの呼び出しの間で例外が発生する可能性があるため、コードは非常に例外的に安全ではなくなりdeleteます。
  • それらは不明確なセマンティクスにつながります: どのポインターを使用する必要があり、どのポインターを使用すべきではないdeleteのでしょうか?
于 2013-11-05T16:46:09.927 に答える