【问题标题】:Boost smart pointers: Can I express it in a more concise way?Boost smart pointers:我能用更简洁的方式表达吗?
【发布时间】:2011-04-04 18:30:33
【问题描述】:

今天我一直在使用 Boost::shared_ptr,我有一个问题。

vector<shared_ptr<KlasaA> > vec;
vec.push_back(shared_ptr<KlasaA>(new KlasaB));
vec.push_back(shared_ptr<KlasaA>(new KlasaC));
vec.push_back(shared_ptr<KlasaA>(new KlasaC));
vec.push_back(shared_ptr<KlasaA>(new KlasaA));

for (vector<shared_ptr<KlasaA> >::const_iterator c_it = vec.begin();
    c_it != vec.end(); ++c_it)
{
    cout << c_it->get()->foo(10) << endl;
}

上面的循环通过一个向量并多态调用foo(10)。

我的问题是:

可以...

for (vector<shared_ptr<KlasaA> >::const_iterator c_it = vec.begin();
    c_it != vec.end(); ++c_it)

和

cout << c_it->get()->foo(10) << endl;

用更简洁的方式表达?提前致谢。

【问题讨论】:

    标签: c++ boost shared-ptr smart-pointers


    【解决方案1】:
    typedef boost::shared_ptr<KlasaA> SharedKlasaA;
    typedef vector<SharedKlasaA> KlasaAVector;
    
    KlasaAVector vec;
    vec.push_back(SharedKlasaA(new KlasaB));
    ...
    for (KlasaAVector::const_iterator ...
    
    cout << (*c_it)->foo(10);
    

    【讨论】:

      【解决方案2】:

      您可以使用Boost.Foreach 库。然后它看起来会非常简洁明了:

      BOOST_FOREACH( boost::shared_ptr<KlasaA> v, vec )
      {
          std::cout << v->foo(10) << std::endl;
      }
      

      【讨论】:

      • 这是一个很好的解决方案,但我个人不喜欢将该变量称为“it”,因为它不是 c++ std 库意义上的迭代器。
      • 我选择了这个答案,因为我不知道 Boost 提供了这么好的 FOREACH。谢谢!
      【解决方案3】:

      据我所知,您的迭代器初始化似乎尽可能紧凑。如果你真的想,你可以把循环函数写成:

      cout << (*c_it)->foo(10) << endl;
      

      这样只节省了 4 个字符,但看起来确实清晰了一些。

      【讨论】:

        【解决方案4】:

        shared_ptr 有一个隐式向下转型的构造函数,所以你可以写

        vec.push_back(shared_ptr<KlasaB>(new KlasaB));
        

        注意 shared_ptr 类型是 shared_ptr&lt;KlasaB&gt; 并且 vec 期望 shared_ptr&lt;KlasaA&gt;。

        考虑到这一点,您可以将 shared_ptr 构造函数替换为 make_shared 函数调用(无论如何,这实际上可能是首选)。

        vec.push_back(make_shared<KlasaB>());
        

        这将为您省去输入一堆类名的麻烦。 make_shared 接受它将转发的参数,因此 make_shared&lt;X&gt; 是 new X 的一个很好的替代品。

        您可能会注意到这里存在潜在的性能影响:make_shared 数据结构可能(会?)不同,并且存在额外的隐式转换,但编译器可能会优化掉它。配置文件并检查。

        【讨论】:

          【解决方案5】:

          依赖于编译器,你可能会做这样的事情:

          std::foreach(vec.begin(),vec.end(),[](const boost::shared_ptr<KlasaA> &p){
            cout<<p->foo(10);
          });
          

          【讨论】:

          • 如果你使用的是 c++0x,你也可以使用基于范围的 for 循环 -- for( auto const & p : vec ) {}
          • 酷...你知道它在标准中的存在吗?不是和概念一起去掉了吗?
          • 它仍在标准中,尽管我看到您对它之前的定义方式感到担忧。我现在不确定它是如何定义的,所以我不会评论。
          猜你喜欢
          • 2013-10-15
          • 2012-11-15
          • 2012-07-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-29
          • 1970-01-01
          相关资源
          最近更新 更多