2013-08-21 30 views
0

有人能告訴我這兩種方法之間的區別如何使用?返回boost :: shared_ptr和從返回的原始指針構造boost :: shared_ptr有什麼區別?

如果我使用CreateBoostContainer,我的代碼運行良好。但是,如果我使用CreateContainer,則在嘗試在ContainerC上使用shared_from_this時,稍後在函數Foo中的代碼中會收到boost :: bad_weak_ptr異常。我只使用一個線程。

謝謝!

用法:

SceneElementNodeC* poNode(new SceneElementNodeC(CreateBoostContainer())); 
SceneElementNodeC* poNode(new SceneElementNodeC(boost::shared_ptr<SceneElementI>(CreateContainer()))); 

定義:

boost::shared_ptr<SceneElementI> LoaderC::CreateBoostContainer() const 
{ 
    return boost::shared_ptr<SceneElementI>(new ContainerC()); 
} 

SceneElementI* LoaderC::CreateContainer() const 
{ 
    return new ContainerC(); 
} 

SceneElementNodeC:

class SceneElementNodeC 
{ 
    SceneElementNodeC(boost::shared_ptr<SceneElementI> spSceneElement) 
    : m_spSceneElement(spSceneElement) 
    {}; 
} 

ContainerC:

class ContainerC : public SceneElementI, public boost::enable_shared_from_this<ContainerC> 
{ 
    ContainerC() 
    {}; 

    void Foo(VisitorI* poVisitor) 
    { 
     poVisitor->Visit(shared_from_this()); 
    }; 
} 

回答

1

首先,CreateBoostContainer可怕名,Boost庫包含數百個組件,包括幾個容器,shared_ptr是加速的只是一個小部分。如果您後來更改了代碼以返回std::shared_ptr,您必須重命名這些函數,那麼您將其更改爲CreateStdContainer?!

其次你沒有提供完整的代碼,允許問題被複制,所以根據Stackoverflow的規則,你的問題應該被關閉!我猜測,你的類型是這樣定義的:

class ContainerC 
: public SceneElementI, public boost::enable_shared_from_this<ContainerC> 
{ 
    // ... 
}; 

不同的是,在這個函數:

boost::shared_ptr<SceneElementI> LoaderC::CreateBoostContainer() const 
{ 
    return boost::shared_ptr<SceneElementI>(new ContainerC()); 
} 

您初始化shared_ptrContainerC*所以shared_ptr構造能夠檢測到有是一個enable_shared_from_this基類(通過隱式上溯造型到enable_shared_from_this<ContainerC>

儘管在此功能:

SceneElementI* LoaderC::CreateContainer() const 
{ 
    return new ContainerC(); 
} 

在創建shared_ptr之前,通過將指針轉換爲基類,您將失去有關該對象的動態類型的信息。返回的指針是SceneElementI*(我假設)沒有enable_shared_from_this基類,因此當該指針稍後用於初始化shared_ptr時,不可能指出它指向也是派生自類的基類enable_shared_from_this<ContainerC>

你可以做第一個功能也無法做這個工作:

boost::shared_ptr<SceneElementI> LoaderC::CreateBoostContainer() const 
{ 
    SceneElementI* ptr = new ContainerC(); 
    return boost::shared_ptr<SceneElementI>(ptr); 
} 

這是等價的,因爲它創建shared_ptr前的指針轉換爲SceneElement*

shared_ptr是聰明,利用指針型的你即使不被存儲在shared_ptr類型構造它,因此,如果您上溯造型這個指針第一則shared_ptr不能變得聰明。

+0

首先感謝您對差異的闡述,那正是我不明白的地方。 – schluchc

+0

關於CreateBoostContainer的命名,當然這很糟糕,但它只是區分這個問題中的兩個函數。關於第二點,你是對的,但我希望在這種情況下,仍然有機會改善問題(我當然會這樣做),而不是馬上關閉;) – schluchc

1

Documentation for enable_shared_from_this

要求:enable_shared_from_this必須是T的一個可訪問的基類 *這必須是類型T的實例t的子對象。 必須存在至少一個擁有t的shared_ptr實例p。

請注意,「必須至少存在一個擁有t的shared_ptr實例p」。

如果您使用CreateContainer那麼沒有shared_ptr實例擁有它。

+0

構造的SceneElementNodeC擁有一個shared_pointer,所以有一個,或者我錯了? – schluchc

1

Using the raw pointer at all is poor form.這就是爲什麼使用類似std::make_shared這樣的典型方法 - 防止任何可能的內存泄漏。考慮一下,在新建類和關聯到智能指針之間可能會引發異常。

話雖如此,我相信這只是助推器enable_shared_from_this如何工作的實現細節。

+0

即使它是一個實現細節,我使用第一種還是第二種方法有什麼區別?在使用shared_from_this時,我看不出有什麼區別,這是構建的SceneElementNodeC擁有shared_pointer時的情況。 – schluchc

相關問題