2011-04-11 62 views
0

我有一個虛擬課basic_action。類sippeers繼承類basic_action。要存儲sippeers類的實例,我正在使用boost::ptr_list。下面是代碼示例:爲什麼在boost :: ptr_list上調用front()時會出錯?

boost::ptr_list<basic_action> ActionsList; 
sippeers spclass; 
ActionsList.push_back(&spclass); 
basic_action *sp = ActionsList.front(); 

在這裏,我創建的prt_list一個實例的指針,以我的basic_action類的實例。 接下來我創建了我的sippeers類的新實例。 接下來,我將指向sippeers類的指針插入ptr_list

最後一個字符串失敗。

Cannot convert from 'basic_action' to 'basic_action *'.

,但有一個內部basic_action *,不basic_action

+6

這無關你的問題,但提高指針容器把你放入其中的對象的所有權。你不想把一個堆棧分配的對象放到一個ptr_list中。 – Ferruccio 2011-04-11 11:48:35

回答

5

boost::ptr_list::front()返回對模板類型的引用,而不是指針。

所以在這種情況下,它返回一個basic_action&

請參閱here的文檔ptr_sequence_adapter,其中ptr_list源自其中。

所以,你的代碼應該閱讀:

boost::ptr_list<basic_action> ActionsList; 
sippeers spclass; 
ActionsList.push_back(&spclass); 
basic_action &sp = ActionsList.front(); 
+0

boost :: ptr_list :: front()返回一個引用。最後一行應該是:basic_action&sp = ActionsList.front(); – Ferruccio 2011-04-11 11:53:27

+0

@Ferruccio謝謝 - 發現我的錯字,大約7分鐘前編輯。 :) – razlebe 2011-04-11 11:55:17

0

如果你看一下header,然後你會看到:

template 
< 
    class T, 
    class VoidPtrSeq, 
    class CloneAllocator = heap_clone_allocator 
> 
class ptr_sequence_adapter 
{ 
public: // construct/copy/destroy 
    template< class InputIterator > 
    assign(InputIterator first, InputIterator last); 
    template< class InputRange > 
    assign(const InputRange& e); 

public: // element access 
    T&  front(); 

(注; ptr_list從ptr_sequence_adapter直接繼承)所以,你所得到的類型,而不是對類型的引用;它會爲您自動解除引用:

basic_action sp = ActionsList.front(); 

是正確的。

+1

我試過使用這種代碼,但Visual Studio生成錯誤:錯誤C2259:'basic_action':無法實例化抽象類。 – CagoBHuK 2011-04-11 11:29:36

+0

@CagoBHuK:那是因爲它不正確。你很幸運,你會得到另一個編譯器錯誤,而不是無意切割的奇怪行爲。 – ltjax 2011-04-11 11:52:51

+0

@CagoBHuK:問題是boost :: ptr_list :: front()返回一個引用。您可以將它分配給一個引用(basic_action&sp = ...),但是如果沒有引用,它會嘗試將引用的對象複製到一個新的basic_action對象(由於它是一個抽象類型,它不能實例化) – Ferruccio 2011-04-11 11:56:46

2

ptr_list :: front()返回對列表中第一個對象的引用。 如果basic_action是一個具體類型,你可以同時使用以下兩種類型。

// 1 
basic_action& sp = ActionsList.front(); 

// 2 
basic_action sp = ActionsList.front(); 

#1將使sp引用列表中的第一個對象。換句話說,通過sp所做的任何更改也會更改列表中的第一個對象。

#2會實例化一個新的basic_action對象,並將列表中第一個對象的內容複製到這個新對象中。對它的任何更改都不會影響列表中的第一項。

如果basic_action是抽象類選項#2不再適用於您,因爲您無法實例化抽象類對象。

此外,您不應該將堆棧分配的對象放入一個boost指針容器中。當ptr_list超出範圍並嘗試刪除其包含的所有對象時,將會發生不好的事情。相反,這樣做:

boost::ptr_list<basic_action> ActionsList; 
ActionsList.push_back(new sippeers); 
basic_action& sp = ActionsList.front(); 
相關問題