讓我們想想一個可能實現的CreateInfoObject
:
void InfoFactory::CreateInfoObject(AbstractInfo** info)
{
*info = new SuperInfo;
}
現在,SuperInfo
和MyInfoObject
不具備共同的權利什麼?
這就是爲什麼,在一般情況下,以下是被禁止的:
struct Base {};
struct D1: Base {};
struct D2: Base {};
int main(int argc, char* argv[])
{
Base** base = nullptr;
D1* d = nullptr;
base = d;
}
因爲這將使D1
指向的東西無關。
有幾種解決方案:
// 1. Simple
AbstractInfo* info = nullptr;
fc.CreateInfoObject(info);
// 2. Better interface
std::unique_ptr<AbstractInfo> info = fc.CreateInfoObject();
然後,如果你知道肯定地說,你,其實,一個MyInfoObject
你可以使用:
MyInfoObject* myInfo = static_cast<MyInfoObject*>(info);
,或者如果您不確定:
MyInfoObject* myInfo = dynamic_cast<MyInfoObject*>(info);
如果有的話,它將設置myInfo
到nullptr
info
未指向MyInfoObject
(或派生)的實例。
但請記住,您的界面真的很可怕。它非常C-ISH,不清楚記憶是否真的被分配......以及誰負責處理它,如果是的話。
編輯:
在良好 C++風格,我們使用RAII雙方表示所有權和確保清理。 RAII是衆所周知的,雖然不是很具有說服力,但我自己更喜歡新的SBRM(Scope Bound Resources Management)。
的想法是,而不是使用裸指針,這並不表明任何所有權(即你必須調用刪除就可以了?),你應該使用智能指針,例如像unique_ptr
。
您也可以使用方法的返回參數,以避免有兩個步驟的初始化過程(首先創建指針,然後使其指向一個對象)。這裏有一個簡明的例子:
typedef std::unique_ptr<AbstractInfo> AbstractInfoPtr;
// Note: if you know it returns a MyInfoObject
// you might as well return std::unique_ptr<MyInfoObject>
AbstractInfoPtr InfoFactory::CreateInfoObject()
{
return AbstractInfoPtr(new MyInfoObject());
}
// Usage:
int main(int argc, char* argv[])
{
InfoFactory factory;
AbstractInfoPtr info = factory.CreateInfoObject();
// do something
} // info goes out of scope, calling `delete` on its pointee
在這裏,關於所有權沒有歧義。
此外,請注意你如何更好地理解你的問題在這裏:
std::unique_ptr<MyInfoObject> info = factory.CreateInfoObject();
不會編譯,因爲你不能轉換AbstractInfo*
爲MyInfoObject*
,而無需使用static_cast
或dynamic_cast
。
編輯討論您的評論! – 2010-09-27 21:10:18
@Tony:我編輯了我的答案,提供了一個替代接口的提案。 – 2010-09-28 06:28:24
非常感謝您的解釋。現在我還可以從檢索到的AbstractInfoPtr中進行下拉式轉換爲派生的對象嗎?這是一個好主意嗎? – 2010-09-28 07:25:38