2012-02-06 46 views
0

我正在C++中进行计算,它必须尽可能快(它可能每秒执行60次,并且可能有大量数据)。在计算过程中,必须处理一定数量的项目。但是,在不同的情况下,物品存储的不同实现是最佳的,所以我需要为此使用抽象类。处理未知容器中所有物品的最有效方法?

我的问题是,对C++中的每个项目执行操作的最常见和最有效的方法是什么? (我不需要期间改变容器的结构)。我已经想到了两个可能的解决方案:

  1. 让迭代器的存储类。 (他们也是我的,所以我可以添加它。)这是在Java中常见的,但似乎并没有很“C”对我说:

    class Iterator { 
    public: 
        bool more() const; 
        Item * next(); 
    } 
    
  2. 添加某种抽象的处理程序,这将是重写在计算部分,将包括代码被称为在每个项目上:(只有一个函数指针是不够的,因为它也带来了一些其他数据)

    class Handler { 
    public: 
        virtual void process(Item &item) = 0; 
    } 
    

  3. 完全不同的东西?

第二个选择似乎因为实际上可以在不中断一个循环处理项目好一点给我,但它使代码相当混乱,因为我将不得不作出相当多的派生类的。你会建议什么?

谢谢。

编辑:更准确地说,存储数据类型并不仅仅是一个ADT,它的基本方法是只根据一些参数找到其中某些特定的元素子集,然后我需要过程,所以我不能在数组或其他东西中准备好它们。

+5

迭代器不是非常C,但它们*非常* C++。 – 2012-02-06 23:07:33

回答

3
#include <algorithm> 

查看C++标准提供的现有容器和函数,如for_each

有关C++容器迭代与“现代”语言中接口的比较,请参阅this answer of mine。其他答案有很好的例子,说明惯用的C++方式在实践中的样子。

使用模板仿函数,正如标准容器和算法一样,它肯定会为您提供虚拟调度的速度优势(尽管编译器有时可能会虚拟化调用,不要指望它)。

+0

只是为了确认,我是否正确理解我应该基本上使用第二种方法,但是使用模板而不是虚拟方法? – Detheroc 2012-02-06 23:27:19

+2

@Detheroc:如果你实现了一个迭代器(duck-typed,非虚拟继承)作为标准容器,那么你可以免费获得所有现有的标准算法,例如'for_each'和'transform'。如果你真的在制作一个容器,那就是我会做的。从你的问题中,你想要为一组生成的项目执行回调,在这种情况下,如果你关心性能,我会用#2去接受一个仿函数。 – 2012-02-06 23:35:17

+0

好的,谢谢澄清,但函子模板存在问题。我无法将它传递给抽象容器,因为虚拟方法不能被模板化。但是我对如何只调用一次虚拟方法而不是所有项目有一些想法,所以非常感谢。 – Detheroc 2012-02-06 23:59:29

0

函数模板或许是:

template <typename C> 
void process(C & c) 
{ 
    typedef typename C::value_type type; 
    for (type & x : c) { do_something_with(x); } 
} 

迭代将使用容器迭代器,通常是有效率,你可以得到。

您可以专门为特定容器模板。

3

C++已经有迭代器。这不是一个特别“Java”的东西。(请注意,它们的界面不同,但它们的效率远远高于它们的Java版本)

至于第二种方法,如果你想为每个元素调用一个虚拟函数会损害性能担心吞吐量。

如果您可以(预先)对数据进行排序,以便所有相同类型的对象都被连续存储,那么您可以选择函数一次,然后将其应用于该类型的所有元素。否则,你将不得不通过虚拟函数或其他机制的间接/类型检查来为每个单独的元素执行适当的操作。

1

是什么让你觉得迭代器不是非常类似C++的?标准库充满了它们(请参阅this),并包含各种算法,可用于在各种标准容器类型上有效执行任务。

如果您使用STL容器,您可以节省重新发明车轮并轻松访问各种预定义的算法。这几乎总是比使用专门的迭代解决方案编写自己的等效容器更好。

+2

他特定的迭代器API不是惯用的C++。 'more'应该叫做'operator!=(end)','next'应该被分成'operator *()'和'operator ++()'。 – 2012-02-06 23:08:19

+1

@BenVoigt:不反对。 C++中的迭代器与其他语言完全不同(OP的例子更像Java),但确实存在。 OP似乎(对我而言)认为迭代器(通常)不是非常类似C++的,但我承认他可能意味着他描述的特定风格不是C++类。无论如何,关键在于STL *包含标准容器的迭代器,使用这种方法的IMHO总是比家庭式解决方案(当然可行)更可取。 – Mac 2012-02-06 23:10:52

相关问题