[英]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_derivedInterface
和m_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.