我有一個層次結構的操作和(共享)信息類,直觀地看起來好像不需要運行時多態性,但是如果沒有它,我無法找到解決方案。具有循環依賴性的CRTP
爲了這個問題,假設有一個2級的層次結構。有一個基本操作和派生操作。來自同一級別的層次結構的對象可能需要在它們之間共享信息(這意味着基礎操作對象需要共享基礎信息,並且派生操作對象需要共享派生信息,但基礎操作對象永遠不需要共享派生信息或副作用反之亦然)。
所以它開始像這樣:
// Shared between base operation objects
class base_info
{
};
// Shared between derived operation objects
class derived_info :
public base_info
{
};
由於沒有運行時的問題,哪些操作對象共享哪些信息的對象,也有以下幾點:
template<class Info>
class base_op
{
std::shared_ptr<Info> m_info;
};
class derived_op :
public base_op<derived_info>
{
};
休息的代碼總是使用base_information
實例化base_op
,因此不需要運行時多態性直到此處。
現在,在某些時候,共享信息對象可以決定他們需要產生新的操作。如上所見,操作對象需要共享指向共享信息對象的指針。因此,信息的層次結構變爲:現在
// Shared between base operation objects
class base_info :
private std::enable_shared_from_this<base_info>
{
void do_something_spawning_new_ops();
};
...
的問題是如何實現do_something_spawning_new_ops
。隨着運行時間polymporphism,它並不難:
class base_info :
private std::enable_shared_from_this<base_info>
{
void do_something_spawning_new_ops()
{
// Need a new op.
get_op_shared_ptr();
}
virtual std::shared_ptr<base_op> get_op_shared_ptr()
{
// use shared_from_this, create a base_op object using it.
}
};
class derived_info :
public base_info
{
virtual std::shared_ptr<base_op> get_op_shared_ptr()
{
// use shared_from_this + std::*_pointer_cast,
// create a derived_op object
}
};
,但關鍵是要避免運行時多態性,由於設計,一切都可以在實例是已知的。所以要回文章的開頭,這本來是很高興有這樣的事情:
template<class Op>
class base_info
{
};
class derived_info :
public base_info<derived_op>
{
};
與CRTP排序啄的(雖然沒有推導),其中運說,它擁有的信息創建這種類型的對象。但是這現在導致base_op
實例化的循環問題。它不知何故需要通過一些信息類型實例化,這些信息類型本身是通過它自己的類型實例化等等。我不知道如何制止這種類型循環。
編輯
繼潘塔大黃的建議,here是我的目標代碼。
CRTP涉及從基地向下廣播到派生。我在這裏的任何地方都看不到。請提供說明問題的完整但最低限度的代碼示例。 –
循環依賴可以通過延遲模板實例化來解決。這可以通過添加另一個圖層來完成。 – rpress
你一直留下很多未知/模糊的東西在你的問題。請提供[MCVE](http://stackoverflow.com/help/mcve),或至少鏈接到一個例如使用像[Ideone](http://ideone.com/)這樣的在線IDE。 –