1

私はc ++で次のコードを持っています:

#include <iostream>;
#include <vector>;

class A
{
public:
    A(int n = 0) : m_n(n) { }

public:
    virtual int value() const { return m_n; }
    virtual ~A() { }

protected:
    int m_n;
};

class B
    : public A
{
public:
    B(int n = 0) : A(n) { }

public:
    virtual int value() const { return m_n + 1; }
};

int main()
{
    const A a(1);
    const B b(3);
    const A *x[2] = { &a, &b };
    typedef std::vector<A> V;
    V y;
    y.push_back(a);
    y.push_back(b);
    V::const_iterator i = y.begin();

    std::cout << x[0]->value() << x[1]->value()
        << i->value() << (i + 1)->value() << std::endl;

    system("PAUSE");

    return 0;
}

コンパイラは結果を返しました: 1413。

正しい結果は 1414 (仮想関数として) になると思っていたので、少し混乱しています。このプログラムの動作をどのように説明しますか?

4

2 に答える 2

6

オブジェクトをスライスしています。ポリモーフィズムを取得するには、 apointerまたは aを使用する必要がありますreference。この例は、元の例にできるだけ近づけて a を使用するpointerと、必要に応じて機能します。

const A a(1);
const B b(3);

typedef std::vector<const A*> V;
V y;
y.push_back(&a);
y.push_back(&b);
V::iterator i = y.begin();

std::cout << (*i)->value()  << std::endl ;
++i ;
std::cout << (*i)->value()  << std::endl ;
于 2013-05-13T12:45:53.590 に答える
4

ここでオブジェクトのスライスがどのように機能するかを簡単に示します。

const A a(1);
const B b(3);
std::vector<A> y; // so y contains objects of type A

y.push_back(a);   // y[0] is copy-constructed from a
y.push_back(b);   // y[1] is copy-constructed from b

どちらの呼び出しでも、自動生成されたコピー コンストラクターを介してpush_back常に構築されていることに注意してください。AA::A(const A&)

B また、 a is-a A、つまりb暗黙的に an にキャストしAて同じコピーコンストラクターに渡すことができることにも注意してください。

したがって、はからコピーされた値を持つ のy[1]インスタンスですが、その仮想関数は依然としてです。値が返されたときではなく、初期化時にコンストラクターで値を変更すると、期待どおりの結果が得られます。Am_nbA::valueB::B

于 2013-05-13T12:53:35.357 に答える