簡體   English   中英

返回boost :: shared_ptr和從返回的原始指針構造boost :: shared_ptr有什么區別?

[英]What is the difference between returning a boost::shared_ptr and constructing a boost::shared_ptr from a returned raw pointer?

有人可以按以下說明告訴我這兩種方法之間的區別嗎?

如果我使用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());
    };
}

enable_shared_from_this的文檔

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

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

如果使用CreateContainer ,則沒有擁有它的shared_ptr實例。

完全使用原始指針是糟糕的形式。 這就是為什么通常使用類似std::make_shared類的東西以防止任何可能的內存泄漏的原因。 考慮到在您創建新類的時間與將其與智能指針相關聯的時間之間可能會引發異常。

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

首先, CreateBoostContainer是一個糟糕的名字,Boost庫包含數百個組件,包括幾個容器, shared_ptr只是Boost的一小部分。 如果以后更改代碼以返回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());
}

您可以使用ContainerC*初始化shared_ptr ,以便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不會很聰明。

暫無
暫無

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

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