2016-09-20 71 views
2

我們在聚類算法創建了三個STL和STL-繼承的數據類型使用的處理:刪除()STL多繼承

typedef std::vector<double>Point; // A list of parameters (a single observation) 

struct Cluster : std::list<Point> { // A list of Points 
    // Additional member variables 
    Point centroid; 
    bool centroid_valid; 
    bool sort_valid; 
    // Cluster functions omitted 
}; 

struct Universe : std::list<Cluster> { // A list of Clusters 
    // No member variables 
    // Universe functions omitted 
}; 

這是試圖充分利用STL所以沒有什麼是new '成立。值得關注的是具有次級STL官能團的性質做的,具體是:

如果我們remove()一個Cluster元素從Universe名單,將在STL處理所有Point S的不僅刪除(和內存管理)在Cluster被刪除,還刪除處理所有成員變量?

注意:所有的成員函數都比較簡單,沒有靜態操作。

+3

是的。但繼承標準容器是一個糟糕的主意。一個宇宙*具有許多簇,但這不是它*所有的*。 –

+1

這些類型的標準容器並非真正意圖被繼承。 –

+1

下面是不繼承的另一個原因:假設將來您需要將集羣的存儲設置爲一個特徵矩陣,以便操作可以在整個矩陣中進行批處理和優化。你不希望你的接口被強制進入STL接口,而是適合你的數據類型:'Cluster :: AddPoint()'。 – Peter

回答

3

如果我們從宇宙列表中刪除()羣集元素,將 所有 點的STL手柄不僅刪除(和內存管理)的集羣被刪除,同時也刪除處理 所有成員變量?

是的,它會因爲它對羣集對象進行操作並刪除它將刪除它的所有字段。但是從標準容器的繼承被認爲是一種糟糕的做法,因爲它們沒有虛擬析構函數。最好將屬性列表中的點列表存儲爲屬性。

+0

謝謝 - 您可以擴展您的意思嗎?「最好將屬性列表作爲屬性存儲在羣集中?」 – Miller

+1

@Miller它意味着最好是聚合而不是繼承。 – Slava

1

錯誤:

typedef std::vector<double>Point; // A list of parameters (a single observation) 

struct Cluster : std::list<Point> { // A list of Points 
    // Additional member variables 
    Point centroid; 
    bool centroid_valid; 
    bool sort_valid; 
    // Cluster functions omitted 
}; 

權:

typedef std::vector<double>Point; // A list of parameters (a single observation) 

struct Cluster { // A list of Points 

    std::list<Point> points; 

    // Additional member variables 
    Point centroid; 
    bool centroid_valid; 
    bool sort_valid; 
    // Cluster functions omitted 
}; 

當你從一個類繼承,你是天生保證其所有成員函數的行爲時,三立對叫你的類。

你的問題在於'額外的成員變量'是點的緩存觀察。如果您點eraseinsert一個點,這些緩存的觀測將不同步,因此錯誤

如果您希望Cluster與std :: list具有相同的接口,那麼您必須實現該接口,調用成員points並更新(或標記爲無效)緩存的觀察值。