我有一个接口类:
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()的返回值(返回一个包含目标子类名称的字符串。)?
答案 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;
}