首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >包装STL以扩展

包装STL以扩展
EN

Stack Overflow用户
提问于 2012-08-14 04:19:04
回答 3查看 768关注 0票数 3

所以我读到从STL继承不是一个好主意。但是将STL类包装在其他类中以扩展它们会怎么样呢?这样做的主要目的是分离抽象层次,以及其他东西。

类似于:

代码语言:javascript
运行
复制
template<class T>
class MyVector{
public:
T& last(){
  return data[data.size() - 1]
}

bool include(T& element);

//etc.

private:
vector<T> data;
}

这是个好主意吗?这是c++程序员经常做的事情吗?

谢谢。

EN

回答 3

Stack Overflow用户

发布于 2012-08-14 04:25:04

是的,包装比继承更好,但仅当您需要向现有数据结构添加状态时。否则,添加非成员函数。这在C++编码标准(Amazon)的第35项中有更详细的解释。

添加状态,首选组合而不是继承。诚然,必须为您想要保留的成员函数编写直通函数是很繁琐的,但这样的实现比使用公共或非公共继承要好得多,也更安全。

代码语言:javascript
运行
复制
template<typename T>
class MyExtendedVector
{
public:
    // pass-through functions for std::vector members
    void some_existing_fun() { return vec_.some_existing_fun(); }

    // new functionality that uses extra state
    void some_new_fun() { // your implementation here }   

private: 
    std::vector<T> vec_;
    // extra state e.g. to do logging, caching, or whatever
};

要添加行为,更喜欢添加非内存函数而不是成员函数。

但是,请确保使您的算法尽可能通用:

代码语言:javascript
运行
复制
// if you CAN: write algorithm that uses iterators only 
// (and delegates to iterator category that container supports)
template<typename Iterator, typename T>
bool generic_contains(Iterator first, Iterator last, T const& elem)
{
    // implement using iterators + STL algorithms only
    return std::find(first, last, elem) != last;
}

// if you MUST: write algorithm that uses specific interface of container
template<typename T>
void vector_contains(std::vector<T> const& v, T const& elem)
{
    // implement using public interface of Container + STL algorithms
    return generic_contains(v.begin(), v.end(), elem);
}
票数 4
EN

Stack Overflow用户

发布于 2012-08-14 04:25:38

我只能说我自己,但我没有这样做,我可能不会建议一般。

在几乎每种情况下,基于迭代器的算法都更易于实现,并将算法与容器分开。例如,假设您的include方法只是确定一个元素是否在向量中,您将根据容器的内容和搜索需要使用findbinary_searchlower_bound

有时,我会通过提供begin/end方法来实现一个在外界看来像容器的类。在这种情况下,它有时在底层有一个标准容器,但您只实现了一个最小的公共接口来表示您的类实际建模的内容。

票数 3
EN

Stack Overflow用户

发布于 2012-08-14 05:05:16

正如最后一个人回答的那样,我会避免这样做。我理解您希望容器将一些更复杂的操作包装到更简单的方法中的方向,并认为您可以在某个时候更改底层容器,而不必更改接口。然而,话虽如此,您的对象应该对您的业务需求进行建模,然后这些对象的实现将使用任何最佳的数据容器和访问模式。我想我想说的是,你不会最终重用这个新的向量类,因为你的业务需求的数据访问每次都会不同,你将再次使用一些标准的通用容器,如std::vector和基于迭代器的algos来访问数据。

现在如果有一些不存在的算法,你可以为特定的项目编写基于迭代器的算法,然后保留算法代码,这样你就可以重用了。下面显示了我基于集合交集编写的一个集合grep算法,但并不完全符合我的要求。我可以改天再用这个算法。

代码语言:javascript
运行
复制
#include <utility>
#include <algorithm>

//  this is a set grep meaning any items that are in set one
// will be pulled out if they match anything in set 2 based on operator pred 
template<typename _InputIterator1, typename _InputIterator2,
  typename _OutputIterator, typename _Compare>
  _OutputIterator
setGrep(_InputIterator1 __first1, _InputIterator1 __last1,
    _InputIterator2 __first2, _InputIterator2 __last2,
    _OutputIterator __result, _Compare __comp)
{
  while (__first1 != __last1 && __first2 != __last2)
    if (__comp(*__first1, *__first2))
      ++__first1;
    else if (__comp(*__first2, *__first1))
      ++__first2;
    else
    {
      *__result = *__first1;
      ++__first1;
      ++__result;
    }
  return __result;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11941670

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档