0
#include <iostream>
#include <string>
#include <map>
#include <vector>

class base {};
class derived1 : public base
{
    public:
        unsigned short n;
        derived1()
        {
            n = 2;
        }
};
class derived2 : public base {};

void main()
{
    // way 1
    {
        std::vector<derived1> a1;
        std::vector<derived2> a2;
        std::map<std::string, base*> b;
        a1.push_back(derived1());
        b["abc"] = &a1.at(0);
        std::cout<<(dynamic_cast<derived1*>(b.find("abc")->second))->n<<std::endl;
    }

    // way 2
    {
        std::map<std::string, base*> b;
        b["abc"] = new derived1();
        std::cout<<dynamic_cast<derived1*>(b.find("abc")->second)->n<<std::endl;
        delete dynamic_cast<derived1*>(b.find("abc")->second);
    }
}

エラーは「'dynamic_cast' : 'base' はポリモーフィック型ではありません」です。これを修正するにはどうすればよいですか? way1 と way2 の両方ですべてが適切にクリーンアップされていますか?

4

1 に答える 1

7

ポリモーフィック型を作成するBaseには、少なくとも1つの仮想関数を指定する必要があります。この場合の最も簡単なのはデストラクタです。

class Base {
public:
  virtual ~Base() { }
};

クリーンアップに関する質問について:
技術的には、ポインターがマップから削除される前にマップが参照するオブジェクトが破棄されるため、両方の方法で未定義の動作がいくつかあります。これにより、マップが破棄されると、無効なポインターが含まれ、未定義の動作が発生します。
実用的な目的では、これによって既知のコンパイラで問題が発生することはありません。

それ以外の場合は、すべてを適切にクリーンアップしています。
しかし、way2では、単純化することができます。仮想デストラクタがある場合Baseは、次のことができます。

delete b.find("abc")->second;

ダイナミックキャストなし。

于 2011-01-09T14:43:09.640 に答える