如何将接口对象强制转换为特定的继承对象

时间:2014-02-18 10:00:37

标签: c++ class c++11 casting type-conversion

我有一个接口类:

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()的返回值(返回一个包含目标子类名称的字符串。)?

4 个答案:

答案 0 :(得分: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要快得多,因为它不需要任何反射或遍历继承树。

答案 1 :(得分:0)

你应该使用dynamic_cast&lt;&gt;: http://en.cppreference.com/w/cpp/language/dynamic_cast



您可以比较字符串并编写if / else来转换指针。

答案 2 :(得分: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;
}

答案 3 :(得分: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;
 }