5

我试图了解在继承场景中指针和模板之间的最佳解决方案是什么。

考虑以下类。

class Event
{
};

class Filter
{
    public:
        virtual void process(Event *event) = 0;
};

class Pipeline
{
    private:
        std::vector<Filter*> _filters
};

每个用户都可以扩展 Event 类和 Filter 类来保存实际数据和实际过滤功能。管道类仅将过滤器与队列连接在一起并执行方法过程。

到目前为止,我一直使用指针来处理继承,例如过滤器指针的 std::vector 和接收事件指针的进程函数。可以使用模板代替指针吗?

例如

class Event
{
};

template<class Event> class Filter
{
    public:
        virtual void process(Event *event) = 0;
};

template<class Filer> class Pipeline
{
    private:
        std::vector<Filter> _filters
};

这是否可行,甚至可能,主要影响是什么?

我还有一个例子要讨论。考虑以下代码:

template<class Element, class Cluster>
Cluster* closestCluster(Element *e, std::vector<Cluster*> &clusters)
{
    double minDist = clusters[0]->distance(e);
    Cluster *c = clusters[0];
    for(std::size_t i = 1 ; i < clusters.size(); ++i)
    {
         double tmp = clusters[i]->distance(e);
         if(tmp < minDist)
         {
             minDist = tmp;
             c=clusters[i];
         }
    }
    return c;
}

Cluster* closestCluster(Element *e, std::vector<Cluster*> & clusters)
{
    double minDist = clusters[0]->distance(e);
    Cluster *c = clusters[0];
    for(std::size_t i = 1 ; i < clusters.size(); ++i)
    {
        double tmp = clusters[i]->distance(e);
        if(tmp < minDist)
        {
            minDist = tmp;
            c=clusters[i];
        }
     }
     return c;
}

乍一看,我看这个功能,虽然没有太大的区别。但在我的代码中,只有第一个有效。因为我的集群数组属于这种类型:

std::vector<KMedoidCluster*> &clusters

我以为编译器可以理解 KMedoidclsuter 是基类 Cluster 的扩展。但显然它不起作用,所以为了获得一些灵活性,我不得不使用模板。

4

2 回答 2

3

本质上,您是在用运行时多态性换取编译时多态性。

这意味着对于第二种方法,管道只能由一种类型的过滤器组成,并且必须在编译时知道该类型。第一种方法比这更灵活。

另一方面,第二种方法中的内存管理更简单。但是,您可以使用智能指针和第一种方法来简化事情。

此外,第二种方法可能具有更高的性能。这是否相关是一个不同的问题。

简而言之,我会使用第一种方法,但会使用智能指针而不是原始指针。

于 2013-11-14T12:15:37.477 回答
1

首先,我认为使用模板会起作用。但是您的代码可能会这样写:

class Event
{
};

template<class T1> class Filter
{
    public:
        virtual void process(T1 *event) = 0;
};

 template<class T2> class Pipeline
{
    private:
        std::vector<T2> _filters
};

使用模板的主要优点是,您可以设置 T1 类,不仅是 Event,还可以设置其他类,如 Event1。您可以将 T2 设置为 Filter 或其他类 Filter1。

然而,在这种情况下,这将成为一个缺点。您不能确保您的过滤器类总是可以处理类事件的对象。其他类如 Event1 的对象也可以工作。

最后,我建议你在这种情况下使用指针而不是模板。

我希望这能帮到您。

于 2013-11-14T12:21:49.000 回答