3

私は2つのクラスA(ベース)とB(から派生)を持っていますA

class A { };

class B : public A
{
    int data;
public:
    int get_data() { return data; }
};

これで、基本クラスのポインターを取り、派生クラスの関数を呼び出す関数テストがあります。

void test(A * ptr)
{
    ptr->get_data();
}

しかし、問題はのオブジェクトまたは のオブジェクトptrを指している可能性があります。のオブジェクトを指している場合は問題ありませんが、 のオブジェクトを指している場合は問題です。ABBA

また、 はのオブジェクトのプロパティではないget_data()ため、仮想化したくありません。dataA

のオブジェクトptrを指しているかどうかを確認するにはどうすればよいですか? B私が考えることができる1つの解決策はdynamic_castNULL. それは最善の解決策ですか、それともより良い解決策がありますか?

4

4 に答える 4

5

これは、test関数が嘘をついていることを意味します。Aから派生した型であっても、任意のオブジェクトへのポインターを受け入れると言っていますAが、関数は実際には 以外には機能しませんB。あなたは服用する方がはるかに良いですB*

void test(B* ptr)
{
   ptr->get_data();
]
于 2013-04-20T12:34:32.730 に答える
0

継承は is-a 関係をモデル化します。明らかにあなたのコードでは B は A ではなく、継承は間違ったモデルです。コメントで、囲んでいるより大きな関数に渡されるベクトルがあると述べています。次のいずれかがより適していることをお勧めします。

  1. std::vector<boost::any>
  2. std::vector<boost::variant<A,B>>

編集 ブーストバリアントを使用した例を次に示します。

class A
{
public:
    void DoIt()
    {
        std::cout << "did it!" << "\n";
    }
};

class B
{
public:
    void GetIt()
    {
        std::cout << "got it!" << "\n";
    }
};

typedef boost::variant<A,B> ab_t;
typedef std::vector<ab_t> list_ab;

void test(list_ab& list)
{
    std::for_each(std::begin(list), std::end(list), [](ab_t& item)
    {
        if(A* a = boost::get<A>(&item))
            a->DoIt();
        if(B* b = boost::get<B>(&item))
            b->GetIt();
    });
}
于 2013-04-20T12:52:59.893 に答える
-4

実際には要素 A または B のベクトルがあると言うと、テスト関数は実際には次のようになります。

void test( A ** ptr )

次に、オーバーロード C++ 機能を使用してユーティリティ関数を作成できます。適切な関数が呼び出されます。

void test( A ** ptr ) {
    A * elem;
    int i=0;
    elem = ptr[i++];
    while(elem) {
        testElement(elem);
        elem = ptr[i++];
    }
}

void testElement( A * ptr ) { }
void testElement( B * ptr ) {
    ptr->get_data();
}
于 2013-04-20T13:02:34.977 に答える