使用继承来重定向多个并行层次结构的c++

Use inheritance to redirect with multiple parallel hierarchies C++

本文关键字:并行 层次结构 c++ 继承 重定向      更新时间:2023-10-16

这是我最好的问题总结:

当多个独立的类从多个独立的基类继承每个类时类,我如何使用继承机制来写一个函数从多个这些基类的对象作为参数?

但是最好用例子来解释。

我有一个库,在其API中提供以下类:

class A{..};
class B{..};
这些类的存在是为了向使用模板的应用程序隐藏模板的复杂性。实现涉及模板:
template <Type1>
class AImpl: public A{..};
template <Type2>
class BImpl: public B{..};

问题是我需要一个这样的函数:

void foo(A insta,B instb);

继承机制在这里似乎没有多大帮助,因为如果函数在AImpl内部,它就没有办法为BImpl自动选择正确的Type2(没有动态强制转换列表)。

到目前为止,我的最佳解决方案是将其中一个类模板化两次:

template <Type1,Type2>
class BImpl: public B{
  void foo(A insta);
};

但是这种方法似乎并没有扩展到将AB与几个任意模板化实例结合起来可能有用的情况(这需要一个动态强制转换,仅在确定参数insta实际上是AImpl<Type2>或前面提到的强制转换列表的情况下才有效)。

如果不给AB的用户增加复杂性,是否有可能做到我在这里尝试做的事情,或者是否有更习惯的方法?

谢谢大家。

编辑

根据Bart van Ingen Schenau的回答,这可能无关紧要,但是为了回应Nawaz和Andy Prowl的询问,我制定了以下示例文件。它需要PCL库,但它是工作代码(虽然是我想要实现的一个减少的例子)。

感谢大家的意见。

Features类似于上面的A, Keypoint类似于上面的B。我也在问题中添加了PCL标签。

#include <pcl/features/fpfh.h> //gives pcl::PointCloud, pcl::FPFHSignature33, etc.
//interface
class Keypoints{
  public:
    virtual unsigned int size();
    //more virtual methods here
};
class Features{
  public:
    virtual unsigned int size();
    //more virtual methods here
};
//implementation
template<typename KeypointType>
class KeypointsImpl:public Keypoints{
  public:
    typename pcl::PointCloud<KeypointType>::Ptr keypoints_;
    virtual unsigned int size(){ return keypoints_->size();}
    //more implementations of virtual methods here
};
template<typename FeatureType>
class FeaturesImpl:public Features{
  public:
    typename pcl::PointCloud<FeatureType>::Ptr features_;
    virtual unsigned int size(){ return features_->size();}
    //more implementations of virtual methods here
};
//void removeBadFeatures(Keypoints k,Features f); //<-- would like to have this too
int 
main (int argc, char ** argv)
{
    //Class construction could be done anywhere. 
    Features *f = new FeaturesImpl<pcl::FPFHSignature33>();
    Keypoints *k = new KeypointsImpl<pcl::PointXYZ>();
    int a = f->size();
    int b = k->size();
    //removeBadFeatures(k,f); //will alter f and k in concert
}

如果我理解正确的话,您正在编写一个使用几个独立模板(Aimpl, Bimpl等)的库。为了对库的用户隐藏这一事实,您只公开这些模板(AB等)的非模板化基类。
现在,您有一个函数foo,它需要在两个模板化类型上工作,作为对其基类的引用传入,并且您面临着无法(容易地)推断参数引用的模板的问题。

只有几个选项可以解决这个难题:

  1. 完全按照在基类上工作的操作来写foo(因为这是foo拥有的所有信息)。
  2. 在使用继承隐藏模板的优点上认真地重新考虑你的库设计。
  3. 编写dynamic_cast s的冗长列表,以确定您正在使用哪个派生类。(如果可能的话,最好避免这个选项,因为这是一个真正的噩梦。)