1
#include <iostream>

class A
{
    public:
        virtual ~A() = default;
        virtual void foo(void) = 0;
};

class B : public A
{
    private:
        int x;

    public:
        B(int a) : x(a) {}
        void foo(void) { std::cout << "B: " << x << "\n"; }
};

class Foo
{
    private:
        A* a_ptr;

    public:
        Foo (B& x) { a_ptr = &x; }
        A* get_ptr(void) { return a_ptr; }
        void dummy(void) { std::cout << "Foo: "; std::cout << a_ptr << "\t "<< typeid(*a_ptr).name() << "\n"; a_ptr->foo(); std::cout << "\n"; }
};

int main(void)
{
        B b(10);
        Foo f(b);

        f.dummy();
        return 0;
}

のコンストラクターがFooのオブジェクトへの参照を受け取る場合B、このプログラムは期待どおりに実行されます。つまり、 をa_ptr->foo()呼び出しますB::foo()

ただし、値によってパラメーターを受け入れるようにコンストラクターが変更された場合、 は にa_ptr->foo()解決されA::foo()、結果はpure virtual method called exception

サンプル出力 (参照渡し:):

Foo: 0x7fffe90a24e0      1B
B: 10

出力例 (値渡し):

Foo: 0x7fffc6bbab20      1A
pure virtual method called
terminate called without an active exception
Aborted (core dumped)

なぜこれが起こっているのかについて漠然とした予感があり、私の仮説を証明または反証する可能性のある文献または参考文献を探していますa_ptr。に電話しa_ptr->foo()ます。

ただし、値で渡されa_ptrた場合、コンストラクターが終了すると失われる一時を指します。

VTABLEこれはofと関係があると思いますがA、指を置くことはできません。

4

2 に答える 2

2

タイプ A* の a_ptr への参照によって一時オブジェクト B を割り当てました。コンストラクターの終了時に、この一時オブジェクトは破棄されています。VTABLE も破棄されているため、A::foo と呼ばれ、これは純粋な仮想です。それで、あなたはそれを手に入れました。

于 2020-08-06T21:26:08.233 に答える