2014-11-04 62 views
2
#include<iostream> 

class base{ 
    public: 
    virtual void run(){}; 
    protected: 
    ~base(){std::cout<<"destructor for base"<<std::endl;}; 
}; 

class derived : public base { 
    public: 
    void run(){}; 
    ~derived(){std::cout<<"destructor for derived"<<std::endl;}; 
}; 

void get_type (std::shared_ptr<base> b){ 
    b.reset (new derived); 
    std::cout<<"end of get_type"<<std::endl; 
} 

int main(){ 
    std::shared_ptr<base> b; 
    get_type (b) ; 
    std::cout<<"out of get_type"<<std::endl; 
    b->run(); 
} 

它編譯好,但我得到了分段錯誤。我看着發生了什麼,輸出是get_type 析構函數派生 析構基地 的對C++多態性使用的質疑

結束了get_type 分割故障:11

它會進入get_type並分配其類型。但是,除了這個函數範圍外,它會自動再次破壞類型。然後,因爲它找不到b-> run(),所以它給出了seg錯誤。任何人都知道如何使它工作?我找不到類似的問題。對不起,如果可能重複。

+3

你忘了做'base ::〜base()'virtual – 2014-11-04 19:24:38

+1

編譯所有的警告信息,你應該收到一個關於@AntonSavin聲明的警告。 – 2014-11-04 19:26:23

+1

這並沒有解決它。我也使用-g -Wall -std = C++ 11 -pedantic -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat = 2 -Winit-self -Wmissing-declaration- Wmissing-include-dirs -Wold-style--Woverloaded-virtual -Wredundant-decls -Wshadow -Wign-conversion -Wsign-promo -Wstrict-overflow = 5 -Wswitch-default -Wundef -Werror -Wno-unused for the flag 。沒有警告信息被打印出來。 – user3089810 2014-11-04 19:33:49

回答

3

您的get_type()函數收到您的main函數中定義的shared_ptr的副本。然後它爲此副本分配一個值並返回。當離開get_type函數時,副本按照正常方式釋放其指針。然後在您的main函數中,初始shared_ptr仍未分配,並且在嘗試解除引用以調用run方法時顯然會遇到分段錯誤。

爲了讓算法起作用,您應該向get_type函數中的shared_ptr請求一個非const引用。

PS:正如其他人指出的,你可以使你的基類的析構函數成爲虛擬的。

+0

如果指針通過引用傳遞會發生什麼? – 2014-11-04 19:51:49

+0

我嘗試通過引用傳遞,它工作正常。感謝這些。 – user3089810 2014-11-04 19:53:20

+0

You __SHOULD__使基類的析構函數成爲虛擬的,但它對於'std :: shared_ptr'不是絕對必要的,只適用於其他任何事情。 – 2014-11-04 19:54:52