如何实现类似容器的大类?

时间:2012-12-27 23:05:56

标签: c++ containers

我有一个名为“System”的大班(我想把“System”改为“House”)。系统包含不同类型的对象,例如窗口和门。不能将不同类型的对象视为具有相同的基类。要构建系统,我需要逐个添加不同类型的对象。并且还需要其他方法,例如删除一个,清除所有方法来管理系统。我正在比较两种方法。一种是在System类的接口中实现所有方法。另一种是暴露对象的内部容器,让用户调用容器的方法来完成它。我认为第一个应该更好但是如果我有许多不同的类型,我需要写很多相似的代码吗?有更好的方法吗?感谢。

class System
{
public:
    AddDoor(Door);
    DeleteDoor(Door);
    DeleteAllDoors();
    ...

    AddWindow(Window);
    DeleteWindow(Window);
    DeleteAllWindows();
    ...

    ......

private:
    vector<Door> m_doors;
    vector<Window> m_windows;
}


class System
{
public:
    vector<Door>& Doors();
    vector<Window>& Windows();
    ...

private:
    vector<Door> m_doors;
    vector<Window> m_windows;
}

2 个答案:

答案 0 :(得分:2)

您的实现看起来像这样:

class System {
public:
    #if YOU_ARE_USING_C++11
    template<typename... Args>
    void Add(Args &&... args) {
     GetContainer<T>().emplace_back(std::forward<Args>(args)...);
    }
    #else
    template<typename T>
    void Add(T const & t) {
        GetContainer<T>().push_back(t);
    }
    #endif
    template<typename T>
    void Delete(T const & t) {
        std::vector<T>::iterator position = std::find(GetContainer<T>().begin(), GetContainer<T>().end(), t);
        GetContainer<T>().erase(position);
    }
private:
    template<typename T>
    std::vector<T> & GetContainer();
};

template<>
std::vector<Doors> & System::GetContainer() {
    return m_doors;
}
template<>
std::vector<Windows> & System::GetContainer() {
    return m_windows;
}

这是你想要的东西吗?很难分辨出什么是最好的&#34;设计就在这里,而不是更多地了解你的问题。

话虽如此,有时候,将班级作为公共成员而不仅仅是职能部门可能是适当的。

答案 1 :(得分:2)

面向对象设计的一个关键原则是“隐藏实现细节”[当然,即使不使用面向对象设计时也应该考虑的事项]。

在这种情况下,这意味着您不应该将向量中存储的内容暴露给调用代码。如果您认为“Vector对于这类事物没有好处,我需要使用地图,列表或树,或者......这将意味着至少改变一些代码会对你的其他代码造成什么影响代码,对吗?如果你有很多代码,这不是一件好事。

所以,你的第一个想法是这里提到的两个更好。

让我担心的一件事是,这个类被称为“系统”。这通常意味着该类是God Object - 它包含所有内容并且就是一切。一般来说,一个类应尽可能小而简单。

我不确定你是否有“上帝对象”,但根据Scott Meyers的书“Effective C ++”,它被称为系统(或管理者)的标志是一个警告。

除了(非常好的)模板解决方案之外,还有一个用于存储和检索对象的接口类,然后让它们在别处分别拥有它们 - 你甚至可以为它们分别拥有容器,但仍然只有一个用于添加/删除接口类型的对象的代码集。