从基类指针比较模板化子类的属性

时间:2016-02-10 15:05:28

标签: c++ templates c++11 polymorphism

我有一个派生自父类的类模板。我将孩子存储在矢量Parent*中。我稍后可以使用typeid来确定两个对象是否是同一类型。我想要做的是比较两个相同类型的对象的属性。为简单起见,我省略了将对象存储在向量中,但概念如下所示:

#include <iostream>
#include <typeinfo>
#include <vector>

class Parent{ public: virtual ~Parent(){}};

template<typename T>
class TypedChild : public Parent
{
public:
    virtual ~TypedChild(){}
    T getValue() {return mValue;}
private:
    T mValue;
};

int main()
{

  Parent* child1 = new TypedChild<int>();
  Parent* child2 = new TypedChild<float>();

  std::vector<Parent*> objects;
  objects.push_back(child1);
  objects.push_back(child2);

  if(typeid(*(objects[0])) == typeid(*(objects[1])))
      if(objects[0]->getValue() == objects[1]->getValue()) // compiler error: Parent has no member named getValue
          std::cout << "Success";


  return 0;
}

当然,在这个示例中,我可以在调用TypedChild<int>之前将{dynamic}播放到getValue(),但在实际情况下,对象位于向量中我不知道它们的类型,我只知道它们是相同的类型,因此它们的getValue()函数应该返回相同的类型,因此可以进行比较。

有没有办法进行这种比较?

1 个答案:

答案 0 :(得分:2)

使用您的用例,即使不是不可能,也能够避免dynamic_cast。如果您想获得一个对象的值,则需要使用dynamic_cast,例如:

Parent* child = ...;

auto typedChild = dynamic_cast<TypedChild*>(child):
if ( typedChild )
{
   int val = typedChild->getValue();
}

如果要比较两个对象是否相等,最好的情况是拥有virtual operator==()函数。

class Parent
{
   public:

      virtual ~Parent(){}
      virtual bool operator==(Parent const& rhs) const = 0;

};

template<typename T>
class TypedChild : public Parent
{
   public:
      virtual ~TypedChild(){}
      T getValue() {return mValue;}

      virtual bool operator==(Parent const& rhs) const
      {
         auto derivedRHS = dynamic_cast<TypedChild<T> const*>(&rhs);
         if ( !derivedRHS )
         {
            return false;
         }
         return (this->mValue == derivedRHS->mValue);
      }

   private:
      T mValue;
};