2016-09-20 90 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并更新(或标记为无效)缓存的观察值。