簡體   English   中英

從C ++類返回shared_ptr

[英]Return a shared_ptr from a class C++

我有一個問題與從類返回共享指針有關。 我班的一部分看起來像這樣:

typedef std::shared_ptr<IBaseInterface> IBaseInterfaceSP;
...

IBaseInterfaceSP getMyInterface()
   {
      m_spBase = std::make_shared<IBaseInterfaceSP>( m_derivedInterface);
      return m_spBase;
   }

其中m_derivedInterfacem_spBase都是我的類的私有成員,即:

private:

   IBaseInterfaceSP m_spBase ;

   DerivedInterface m_derivedInterface;

同樣, DerivedInterface繼承自IBaseInterfaceSP

getInterface是我班的一個公共函數。

這是從類中返回指針的正確方法嗎? 切片或類似的東西會有問題嗎?

PS很抱歉,如果有不清楚的地方(不允許將所有代碼公開發布在這里,只有某些部分),如果可以,請告訴我。

我可以看到此代碼的幾個問題。

1.延遲初始化

每次調用getInterface時,都會創建一個IBaseInterface類的新實例。 作為您班級的用戶,我不會從名為“ get”的方法獲得這種行為。

我猜您想實現延遲初始化,在這種情況下,您可以這樣進行:

IBaseInterfaceSP getInterface()
{
    if (!m_spBase)
    {
        m_spBase= std::make_shared<IBaseInterface>( m_derivedInterface );
    }
    return m_spBase;
}

2.命名約定

您正在實例化一個名為IBaseInterface的類,這聽起來像一個抽象類(“ I”前綴在歷史上一直用於接口)。 您可能應該重命名您的類,以使其聽起來不抽象。 另外,“ I”前綴在“ Interface”后綴中是多余的。

但是,在我認為“好的” OOP中,用戶不需要知道您正在向他們提供接口。 因此,不需要將具體類與抽象類區分開的命名約定。

3.所有權語義

共享指針用於共享所有權 :返回共享指針時,您是在告訴類用戶他們也將擁有返回的對象。 通常,不需要。 在大多數情況下,您將返回非所有者指針,也就是原始指針。 例如:

IBaseInterface* getInterface()
{
    return m_spBase.get(); // Instantiation done elsewhere, for example in constructor
}

4.切片

確實有切片發生在這里。 這行:

m_spBase = std::make_shared<IBaseInterface>( m_derivedInterface );

實際上擴展為包含與此等效的代碼:

auto newInstance = new IBaseInterface(m_derivedInterface );

反過來,上面的行將調用IBaseInterface類的副本構造函數,其簽名類似於:

IBaseInterface(IBaseInterface& other)

因此,在該調用的上下文中,m_derivedInterface被解釋為IBaseInterface引用。 因此,在調用“ new”期間僅將復制IBaseInterface的成員,從而丟失存儲在派生類DerivedInterface中的所有信息。


綜上所述,在我看來,您真正想要的是直接訪問m_derivedInterface對象。 您現在正在做的是,將實例復制到另一個對象中並返回新對象。 我認為您真正想要的是:

IBaseInterface* getInterface()
{
    return &m_derivedInterface;
}

如果您堅持使用共享所有權,只需存儲指向m_derivedInterface的共享指針而不是值:

MyClass(Args args)
{
    m_derivedInterface.reset(new DerivedInterface(args));
}

std::shared_ptr<IBaseInterface> getInterface()
{
    return m_derivedInterface;
}

std::shared_ptr<IBaseInterface> m_derivedInterface;

暫無
暫無

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

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