C++继承:模板与指针

C++ inheritance: Templates Vs Pointers

本文关键字:指针 继承 C++      更新时间:2023-10-16

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

请考虑以下类。

class Event
{
};
class Filter
{
    public:
        virtual void process(Event *event) = 0;
};
class Pipeline
{
    private:
        std::vector<Filter*> _filters
};

每个用户都可以展开 Event 类和 Filter 类来保存实际数据和实际筛选函数。管道类仅将筛选器与队列连接在一起,并执行方法进程。

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

例如

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的扩展。但显然它不起作用,所以为了获得一些灵活性,我不得不使用模板。

实质上,您正在将运行时多态性换成编译时多态性。

这意味着,使用第二种方法,管道只能包含一种类型的过滤器,并且该类型必须在编译时已知。第一种方法比这更灵活。

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

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

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

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

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 事件,还可以设置其他类(如 Event1)。您可以将 T2 设置为过滤器或其他类过滤器 1。

然而,在这种情况下,这成为一个缺点。您无法确保 Filter 类始终可以处理类事件的对象。其他类(如 Event1 的对象)也可以工作。

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

我希望这对你有帮助。