为了账号安全,请及时绑定邮箱和手机立即绑定

从STL容器继承实现而不是委托可以吗?

从STL容器继承实现而不是委托可以吗?

C++
跃然一笑 2019-06-28 11:10:26
从STL容器继承实现而不是委托可以吗?我有一个类来适应std:vectory来建模特定于域的对象的容器。我希望向用户公开大部分STD:VectorAPI,以便他/她可以使用熟悉的方法(大小、清除、at等)。以及容器上的标准算法。在我的设计中,这似乎是一种反复出现的模式:class MyContainer : public std::vector<MyObject>{public:    // Redeclare all container traits: value_type, iterator, etc...    // Domain-specific constructors    // (more useful to the user than std::vector ones...)    // Add a few domain-specific helper methods...    // Perhaps modify or hide a few methods (domain-related)};我知道在为实现重用类时更喜欢组合而不是继承的做法-但是一定会有限制的!如果我将所有内容委托给std:vectoral,那么就会有32个转发函数!所以我的问题是.。在这种情况下继承实现真的那么糟糕吗?风险有多大?有没有更安全的方法,我可以实现这一点,而不需要这么多的打字?我是一个使用实现继承的异端者吗?:)编辑:如何明确说明用户不应通过std:Vectoral<>指针使用MyContainer:// non_api_header_file.hnamespace detail{    typedef std::vector<MyObject> MyObjectBase;}// api_header_file.hclass MyContainer : public detail::MyObjectBase{    // ...};Boost库似乎一直在做这件事。编辑2:其中一项建议是使用免费功能。我将在这里显示为伪代码:typedef std::vector<MyObject> MyCollection;void specialCollectionInitializer(MyCollection& c, arguments...);result specialCollectionFunction(const MyCollection& c);etc...一种更OO的方法:typedef std::vector<MyObject> MyCollection;class MyCollectionWrapper{public:    // Constructor    MyCollectionWrapper(arguments...) {construct coll_}    // Access collection directly    MyCollection& collection() {return coll_;}     const MyCollection& collection() const {return coll_;}    // Special domain-related methods    result mySpecialMethod(arguments...);private:    MyCollection coll_;    // Other domain-specific member variables used    // in conjunction with the c
查看完整描述

3 回答

?
慕斯王

TA贡献1864条经验 获得超2个赞

正如大家已经说过的,STL容器没有虚拟析构函数,因此从它们继承最多是不安全的。我一直认为使用模板进行通用编程是一种不同风格的OO-一种没有继承的OO。算法定义了它们所需的接口。就像鸭型你可以使用静态语言。

无论如何,我确实有一些东西要补充到讨论中。我以前创建自己的模板专门化的方法是定义如下类作为基类。

template <typename Container>class readonly_container_facade {public:
    typedef typename Container::size_type size_type;
    typedef typename Container::const_iterator const_iterator;

    virtual ~readonly_container_facade() {}
    inline bool empty() const { return container.empty(); }
    inline const_iterator begin() const { return container.begin(); }
    inline const_iterator end() const { return container.end(); }
    inline size_type size() const { return container.size(); }protected: // hide to force inherited usage only
    readonly_container_facade() {}protected: // hide assignment by default
    readonly_container_facade(readonly_container_facade const& other):
        : container(other.container) {}
    readonly_container_facade& operator=(readonly_container_facade& other) {
        container = other.container;
        return *this;
    }protected:
    Container container;};template <typename Container>class writable_container_facade: public readable_container_facade<Container> {public:
    typedef typename Container::iterator iterator;
    writable_container_facade(writable_container_facade& other)
        readonly_container_facade(other) {}
    virtual ~writable_container_facade() {}
    inline iterator begin() { return container.begin(); }
    inline iterator end() { return container.end(); }
    writable_container_facade& operator=(writable_container_facade& other) {
        readable_container_facade<Container>::operator=(other);
        return *this;
    }};

这些类公开与STL容器相同的接口。我确实喜欢将修改操作和非修改操作分离为不同的基类的效果。这对康斯特正确性有很好的影响。一个缺点是,如果要将接口与关联容器一起使用,就必须扩展接口。不过,我还没有遇到这种需要。


查看完整回答
反对 回复 2019-06-28
  • 3 回答
  • 0 关注
  • 588 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信