2014-02-18 3 views
1

У меня есть интерфейс класс:Как бросить объект интерфейса к конкретному унаследованному объекту

Class IOperand 
{ 
    virtual ~IOperand() {}; 

    virtual std::string getType() const = 0; 
} 

И у меня есть несколько унаследовали класса, как это:

class Int8: public IOperand 
{ 
    public: 
     Int8(int8_t _value = 0); 
     virtual ~Int8() {}; 
     virtual std::string getType() const; 

     int8__t getValue() const; 

    private: 
     int8_t _value 
} 

Я использую указатель на типе IOperand, но мне нужно использовать функцию getValue(). Как я могу скрыть объект типа IOperand в объекте типа подкласса в зависимости от возврата getType() (который возвращает строку, связанную с именем целевого подкласса)?

ответ

5

Вы запрашиваете базовый тип для производного типа. Обычно этот вид литья является признаком плохого дизайна, поскольку - в большинстве случаев - базовый тип должен обеспечивать виртуальный метод, который обеспечивает желаемую операцию. Однако в некоторых случаях его необходимо отнести к определенному классу. Есть два способа сделать это.

Неизвестного типа выполнения
Если вы не знаете, является ли тип или не является INT8, то вам нужен полиморфный вниз бросок. Это делается с помощью специального dynamic_cast механизма, как это:

IOperand* operand = // ... 
Int8* casted = dynamic_cast<Int8*>(operand); 
if (casted == nullptr) { 
    // runtime type was not an Int8 
    return; 
} 
// operate on casted object... 

Известного типа выполнения
Если вы абсолютно точно знаете, что тип является подтипом, то вы, вероятно, хотите использовать static_cast. Обратите внимание, однако, что static_cast не будет проверять, что делает dynamic_cast. Однако будет значительно быстрее сделать static_cast, так как он не требует никакого отражения или ходьбы по дереву наследования.

0

Вы могли бы сделать что-то вроде этого:

IOperand *op = function_returning_ioperand_pointer(); 

if (op->getType() == "Int8") { 
    Int8 *int8_op = dynamic_cast<Int8*>(op); 
    if (!int8_op) std::cerr << "Cast failed" << std::endl; 
} 
0

См Википедии Run-time type information article:

/* A base class pointer can point to objects of any class which is derived 
* from it. RTTI is useful to identify which type (derived class) of object is 
    * pointed to by a base class pointer. 
    */ 

#include <iostream> 

class Base 
{ 
public: 
    Base() { } 
    virtual ~Base() { } 

    virtual void hello() 
    { 
     std::cout << "in Base"; 
    } 
}; 

class Derived : public Base 
{ 
public: 
    void hello() 
    { 
     std::cout << "in Derived"; 
    } 
}; 

int main() 
{ 
    Base* basePointer = new Derived(); 
    Derived* derivedPointer = NULL; 

    //To find whether basePointer is pointing to Derived type of object 
    derivedPointer = dynamic_cast<Derived*>(basePointer); 

    if (derivedPointer != NULL) 
    { 
     std::cout << "basePointer is pointing to a Derived class object"; //Identified 
    } 
    else 
    { 
     std::cout << "basePointer is NOT pointing to a Derived class object"; 
    } 

    //Requires virtual destructor 
    delete basePointer; 
    basePointer = NULL; 

    return 0; 
} 
Смежные вопросы