0

2つの簡単なクラスがあります。基本クラスA、および派生クラスB。デバッグの目的で、コピーコンストラクタとデストラクタは次のcoutものにオーバーライドされます。

class A
{
protected:
    char * c;
public:
    A(char * c) : c(c) { cout << "+A " << this << "\n"; }
    A(const A& other) : c(other.c) { cout << "*A " << this << "\n"; }
    ~A() { cout << "-A " << this << "\n"; }
};

class B : public A
{
public:
    B(char * c) : A(c) { cout << "+B " << this << "\n"; }
    B(const B& other) : A(other.c) { cout << "*B " << this << "\n"; }
    ~B() { cout << "-B " << this << "\n"; }
};

これが私がどのようにinsertインスタンスにB入るのかですmap

    {
        cout << "-- 1\n";
        map<string, A> m;
        cout << "-- 2\n";
        m.insert(pair<string, A>( "b", B("bVal")));
        cout << "-- 3\n";
    }
    cout << "-- 4 --\n";

その結果:

-- 1
-- 2
+A 0051F620
+B 0051F620
*A 0051F5EC
*A 00BD8BAC
-A 0051F5EC
-B 0051F620
-A 0051F620
-- 3
-A 00BD8BAC
-- 4 --

インスタンスの作成に関して、私はこれを次のように読みました。

  1. B私自身のコードによって作成されます
  2. によってBコピー構築さAれますpair
  3. その最後のインスタンスは、挿入されAた場所でもう一度コピーされますmap

ところでpairinsert行のをaに変更してpair<string, B>もうまくいきませんでした。2番目のステップを変更して、のB代わりにを作成するだけでしたAが、最後のステップで再度ダウングレードしましたA。マップ自体が破壊の対象となるまで残るマップ内の唯一のインスタンスは、その最後のAインスタンスのようです。

何が間違っているのでしょうか。また、派生クラスをマップに取り込むにはどうすればよいですか。フォーマットのマップを使用する

map<string, A*>

多分?

更新-解決策私の解決策は、受け入れられた回答に直接記載されているのではなく、提案の形でコメントに埋もれているため、最終的には次のようになりました。

map<string, shared_ptr<A>> m;

これは、ビルド環境がshared_ptrsをサポートしていることを前提としています。これは私のもの(C ++ / CLI、Visual Studio 2010)がサポートしています。

4

2 に答える 2

4

これはスライスと呼ばれ、派生クラスが割り当てられたオブジェクトに適合しない場合に発生します。これは、一例です。

B b;
A a = b; // This would only copy the A part of B.

さまざまなタイプのオブジェクトをマップに格納する場合は、正しく推測されているように、map <...、A*>を使用するのが最善の方法です。オブジェクトはマップ内ではなくヒープのどこかに格納されるため、コピーする必要はなく、常に収まります。

于 2012-07-16T07:25:06.103 に答える
2
 map<string, A> m;

挿入されたオブジェクトをスライスAします。これはになり、他のすべての情報を失います(もはやではありませんB)。

あなたの直感は正しいです、あなたはポインターを使う必要があるでしょう、あるいはもっと良いことに、スマートポインターを使う必要があります。

また、のデストラクタは次のようにAする必要がありますvirtual

class A
{
    //...
    virtual ~A() { cout << "-A " << this << "\n"; }
};

Bそれ以外の場合、ポインタを介して実際のタイプのオブジェクトを削除すると、A未定義の動作が発生します。

于 2012-07-16T07:23:15.740 に答える