Tencent/flare

为什么侵入式的链表采用的是组合而不是继承?

4kangjc opened this issue · 5 comments

struct DoublyLinkedListEntry {
  DoublyLinkedListEntry* prev = this;
  DoublyLinkedListEntry* next = this;
};

template <class T>
class DoubleLyLinkedList {
public:
  static_assert(std::is_base_of_v<DoublyLinkedListEntry, T>);

private:
  static constexpr T* object_cast(DoublyLinkedListEntry* entry) noexcept {
    return reinterpret_cast<T*>(entry);
  }
  static constexpr DoublyLinkedListEntry* node_cast(T* ptr) noexcept {
    return reinterpret_cast<DoublyLinkedListEntry*>(ptr);
  }

  size_t size_{};
  DoublyLinkedListEntry head_;
};
  // 组合
  struct C {
    DoublyLinkedListEntry chain;
    int x;
  };
  DoublyLinkedList<C, &C::chain> list;
 // 继承
  struct C : public DoublyLinkedListEntry {
    int x;
  };
  DoublyLinkedList<C> list;

通常认为从软件工程角度,角度组合比继承更有助于良好的扩展性及长期的代码维护

See also https://en.m.wikipedia.org/wiki/Composition_over_inheritance

通常认为从软件工程角度,角度组合比继承更有助于良好的扩展性及长期的代码维护

See also https://en.m.wikipedia.org/wiki/Composition_over_inheritance

嗯好

只是刚好想到红黑树里的设计是这样的

struct _Rb_tree_node_base
  {
    typedef _Rb_tree_node_base* _Base_ptr;
    typedef const _Rb_tree_node_base* _Const_Base_ptr;

    _Rb_tree_color	_M_color;
    _Base_ptr		_M_parent;
    _Base_ptr		_M_left;
    _Base_ptr		_M_right;
};

template<typename _Val>
    struct _Rb_tree_node : public _Rb_tree_node_base {
     __gnu_cxx::__aligned_membuf<_Val> _M_storage;
};

只是刚好想到红黑树里的设计是这样的

struct _Rb_tree_node_base
  {
    typedef _Rb_tree_node_base* _Base_ptr;
    typedef const _Rb_tree_node_base* _Const_Base_ptr;

    _Rb_tree_color	_M_color;
    _Base_ptr		_M_parent;
    _Base_ptr		_M_left;
    _Base_ptr		_M_right;
};

template<typename _Val>
    struct _Rb_tree_node : public _Rb_tree_node_base {
     __gnu_cxx::__aligned_membuf<_Val> _M_storage;
};

类似于继承方向指针

作为不对外的内部实现的时候,有时候会更侧重开发成本之类的考量