2016-02-10 3 views
0

У меня есть шаблон класса, который происходит от родительского класса. Я храню детей в векторе как 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; 
} 

Конечно, в этом примере я мог dynamic_cast в TypedChild<int> перед вызовом getValue(), но в реальном случае, когда объекты находятся в векторе я не знаю их типов, я просто знаю, что они одного типа, поэтому их функции getValue() должны возвращать один и тот же тип и, следовательно, можно сравнивать.

Есть ли способ сделать это сравнение?

+0

@BoPersson Они не все одинаковы. Я хочу хранить объекты, накладываемые шаблонами на любой тип в векторе. Затем я хочу иметь возможность сравнить два из этих объектов, только если они одного типа. –

+0

@BoPersson Видимо, мое упрощение приносило больше вреда, чем пользы! Я обновил пример, чтобы лучше показать пример использования. Я имел в виду, что я знаю, что два объекта одного типа, потому что я делаю тест сравнения типов с помощью 'typeid()'. –

+0

@DavidDoria Ah. Я ошибся, что ты делаешь. удаление комментариев. – NathanOliver

ответ

2

В вашем случае использования, возможность избежать dynamic_cast будет сложной, если не невозможной. Если вы хотите, чтобы получить значение только одного объекта, вы должны будете использовать dynamic_cast, такие как:

Parent* child = ...; 

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

Если вы хотите сравнить два объекта на равенство, в лучшем случае, чтобы иметь virtualoperator==() функция.

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; 
}; 
+0

Отлично, это именно то, что мне нужно, спасибо! –

+0

Я бы на самом деле выполнил проверку типа и static_cast вместо dynamic_cast, так как сравнение равенства может срезать для сравнения, полученные из TypedChild . – Nevin

Смежные вопросы