簡體   English   中英

為什么基 class 指針指向基 class 中的純虛方法,而不是派生 class 中的覆蓋方法?

[英]Why does the base class pointer point to the pure virtual method in the base class instead of the overidden method in the derived class?

#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的 object ,那么這個程序將按照我期望的方式執行,即a_ptr->foo()調用B::foo()

但是,如果將構造函數更改為按值接受參數,則a_ptr->foo()將解析為A::foo() ,並導致pure virtual method called exception

樣品 output(通過引用傳遞:):

Foo: 0x7fffe90a24e0      1B
B: 10

示例 output(按值傳遞):

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

我對為什么會發生這種情況有一種模糊的預感,我正在尋找一些可能證明或反駁我的假設的文獻或參考:當通過引用傳遞時,基本 class 指針a_ptr指向一個生命周期超過過去的實體對a_ptr->foo()的調用。

但是,當按值傳遞時, a_ptr指向一個臨時對象,該臨時對象在構造函數退出時會丟失。

我想這與AVTABLE有關,但我不能完全理解它。

是的,你的懷疑是正確的。

B object 被傳Foo構造函數中時,就變成了構造函數的局部變量。 構造函數正在保存指向本地 object 的指針,當構造函數退出時,該指針從 scope 中消失。

因此,在Foo::dummy()中對a_ptr->foo()的調用實際上是未定義的行為,因為a_ptr甚至沒有指向有效的 object 開始。 但是,它並沒有真正崩潰,因為A::foo()沒有使用它的this指針做任何事情。 它只是指向一個編譯器定義的 function ,它拋出了一個pure virtual method called ,你沒有捕捉到它,所以你的程序終止了。

您通過引用 A* 類型的 a_ptr 分配了臨時 object B。 在構造函數退出時,此臨時 object 已被銷毀。 由於 VTABLE 也被銷毀,稱為 A::foo,它是純虛擬的。 所以你明白了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM