mar*_*nes 5 c++ inheritance templates pointers
我试图了解继承方案中指针和模板之间的最佳解决方案.
考虑以下类.
class Event
{
};
class Filter
{
public:
virtual void process(Event *event) = 0;
};
class Pipeline
{
private:
std::vector<Filter*> _filters
};
Run Code Online (Sandbox Code Playgroud)
每个用户都可以展开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
};
Run Code Online (Sandbox Code Playgroud)
这是否有效,甚至是可能的,主要含义是什么?
我有另一个例子来讨论.请考虑以下代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
乍一看,我看这个功能,虽然没有太大的区别.但在我的代码中只有第一个有效.因为我的簇数组是这种类型:
std::vector<KMedoidCluster*> &clusters
Run Code Online (Sandbox Code Playgroud)
我认为编译器可以理解KMedoidclsuter是基类Cluster的扩展.但显然它不起作用,所以为了获得一些灵活性,我不得不使用模板.
本质上,您是在用运行时多态性换取编译时多态性。
这意味着使用第二种方法时,管道只能包含单一类型的过滤器,并且该类型必须在编译时已知。第一种方法比这更灵活。
另一方面,第二种方法的内存管理更简单。但是,您可以将智能指针与第一种方法一起使用来简化事情。
此外,第二种方法可能性能更高。这是否相关是另一个问题。
简而言之,我会使用第一种方法,但会使用智能指针而不是原始指针。