3

クラス BaseClass 内に public 関数があります。

virtual void Call(){};

派生クラス Archer の内部には、次の関数があります。

void Call(){ cout << "whatever" << endl; };

私もベクトルを設定しています:

vector<BaseClass> classes;

ここで、BaseClass から派生した 3 つのクラスをプッシュします。問題は、次のようなメソッドを介してベクターにプッシュしているにもかかわらず、BaseClass への参照から Call() を呼び出していることです (私にはおそらく間違っています)。

BaseClass Player::CharChoice(string character)
{
    if(character == "Archer") return *new Archer();
    else if(character == "Knight") return *new Knight();
    else if(character == "Sorcerer") return *new Sorcerer();
    else cerr << "CHARACTER NOT DEFINED" << endl;
};

for(int c = 0; c < chars.size(); c++)
{
    classes.push_back(CharChoice(chars[c]));
}

代わりに次のような変数を設定すると:

Archer *archer = new Archer();

Call() を呼び出すと、意図したとおりに機能します。私はC++にかなり慣れていないため、これに対する解決策を考え出すことができません。

4

1 に答える 1

4

ヒープではなくスタック上にオブジェクトを作成すると、継承の価値の多くが失われます。仮想関数は失うものの 1 つです。仮想関数で正しい関数を呼び出すには、オブジェクトをポインターまたは参照として渡し、newそれを作成するために使用する必要があります。

Base * b = new Derived();    // or  
Base & b = * new Derived();  

ベクトルは、参照またはポインターを格納する必要があります。

vector<BaseClass*> classes;
vector<BaseClass&> classes;

一般的な要求により、これを処理する最も簡単な方法は次のとおりです。std::shared_ptr

vector<shared_ptr<BaseClass>> classes;

これらの 1 つは、次のように作成されます。

shared_ptr<BaseClass> ptr(new BaseClass);

基本的に、shared_ptr はメモリ管理の厄介なタスクを処理します。

同じオブジェクトに複数のptrが必要な場合はshared_ptrが適していますが、そうでない場合は使用できますstd::unique_ptr

vector<unique_ptr<BaseClass>> classes;

次のように作成します。

unique_ptr<BaseClass> ptr(new BaseClass);

ご覧のとおり、構文は shared_ptr と非常に似ているため、移行は簡単です。

于 2013-07-01T02:30:46.520 に答える