C++ 组合与迭代器

标签 c++ iterator composition

我会尽量让我的示例代码非常简单明了,但当我在现场输入时可能会出现错误。

我有一个名为 Phone 的类。

class Phone
{
 public:
  Phone(std::string manufacturer, std::string model, std::vector<Feature> features);

 private:
  std::vector<Features> features;
  std::string model;
  std::string manufacturer;
};

我有一个名为 Feature 的结构。

struct Feature
{
   Feature(std::string feature, std::string category);
   std::string feature;
   std::string category;
};

如您所见,手机有一个功能列表( vector ):即。蓝牙、GPS、 radio 等,其中有一个类别:网络、导航、多媒体。

现在有关手机和功能的信息存储在 sqlite3 数据库中。 我有一个辅助函数,它将从数据库中检索特定的电话型号并返回一个填充的电话对象。 我还有一个接收电话对象并将电话写入数据库的函数。

问题是我需要为客户提供某种方法来遍历电话功能列表。对于初学者来说,数据库助手需要了解这些特性,以便将它们写入数据库。其次,客户端可能需要从数据库中检索电话,然后向用户显示功能列表。

一种解决方案是在Phone类中添加以下函数

std::vector<Feature>::iterator begin()
std::vector<Feature>::iterator end()

这对我来说不是一个理想的解决方案,因为客户端代码看起来不直观 - 看起来好像客户端正在迭代手机,而实际上是在迭代功能。

另一种解决方案在 http://accu.org/index.php/journals/1527 的一篇文章中进行了讨论。其中讨论了使用名为“memberspaces”的技术将迭代器暴露给客户端代码。这会产生更具可读性的客户端代码,但在我看来,实现有点困惑。

迭代器问题是否有更好的解决方案,或者是否有更适合我使用的设计模式。

如有任何反馈,我们将不胜感激。

最佳答案

在你的情况下,我会先选择更好的名字:

typedef std::vector<Feature> Features;

Features::iterator features_begin();
Features::iterator features_end();
Features::const_iterator features_begin() const;
Features::const_iterator features_end() const;

例子:
1)

 // Note: you'll need to define an operator<< for Feature
 // can be used with std::algorithms
 std::copy( phone.features_begin(), phone.features_end(),
   std::ostream_iterator<Feature>( std::cout, "\n\r" ) );     

2)

// Note: shamelessly borrowed from http://www.boost.org/doc/libs/1_44_0/doc/html/foreach/extensibility.html
// add overloads of range_begin() and range_end() for Phone::Features
inline Phone::Features::iterator range_begin( Phone& phone ){
   return phone.features_begin();
}

inline Phone::Features::iterator range_end( Phone& phone ){
   return phone.features_end();
}

namespace boost{
   // specialize range_mutable_iterator and range_const_iterator in namespace boost
   template<>
   struct range_mutable_iterator< Phone >{
      typedef Phone::Features::iterator type;
   };

   template<>
   struct range_const_iterator< Phone >{
      typedef Phone::Features::const_iterator type;
   };
}
...
// can be used with BOOST_FOREACH
BOOST_FOREACH( Feature x, phone ){
   std::cout << x << std::endl;
}

附言鉴于 Jonannes 的建议和 boost::range 使用的命名约定,名称现在是 features_xxx() 而不是 xxx_features()(特别是因为在这种情况下,它们确实更有意义)。

关于C++ 组合与迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3640563/

相关文章:

c++ - string::replace 在有效迭代器上抛出 std::out_of_range

java - 分组类的方式与 PHP 不同吗?

python - python 中的组合和外观是同一件事吗?

c++ - 通过初始化列表在构造函数中初始化类成员( vector )

c++ - 是否可以将 QTreeWidgetItem 的文本部分设为斜体?

c++ - C中的MAX和MIN是什么? #定义函数

c++ - 运行 mastermind 程序时出现 Cygwin 错误

java - [JAVA]数组迭代器的arraylist

java - 我怎样才能在java中进行这个 map 迭代?

java - 是否在被视为组合的方法内从另一个类创建对象