确定性在C++中,对象类型
问题描述:
让我们假设我有两个具有相同的接口确定性在C++中,对象类型
class FirstChild : class Father
{
//some fields and methods useful for class A
}
class SecondChild : class Father
{
//some fields and methods useful for class B
}
后来,在代码类似的东西做
Father* myInstance = new SecondChild();
现在,如果两个类映射两个对象我想知道对象的type
,如果实例是FirstChild或SecondChild,则必须执行一些操作。我正在做类似的事情:
if (typeid (myInstance) == typeid (FirstChild))
{
// do stuff
} else if (typeid (myInstance) == typeid (SecondChild))
{
// do other stuff
}
这是正确的方式吗? 因为某处StackOverflow
,我读了typeid
是不是安全,它是更方便地添加一个虚拟功能,比方说getType
例如,做,在则firstChild
char* getType { return "FirstChild"; }
说实话,我不喜欢这样的解决方案太多了,因为我们似乎忽略了面向对象编程中多态的强大功能。
所以,你们,你觉得呢?在C++中检查子对象类型的最佳方法是什么?
答
一个简单的方法可以使用dynamic_cast
。例如:
Father *myInstance = new SecondChild();
SecondChild *casted = dynamic_cast<SecondChild*>(myInstance);
if (casted != nullptr)
std::cout << "myInstance is a SecondChild!";
else
std::cout << "myInstance is not a SecondChild!";
如果转换成功,dynamic_cast的返回类型NEW_TYPE的值。如果转换失败并且new_type是一个指针类型,它将返回该类型的空指针。如果转换失败并且new_type是引用类型,则会抛出一个与std :: bad_cast类型的处理程序匹配的异常。
正如@Rob指出的那样,您可以使用虚拟函数并让对象自己执行操作。
struct Father
{
virtual void process() = 0;
};
您可以使用虚函数来决定是否应该完成操作,而不是检查类型。
struct Father
{
virtual bool shouldProcess() { return false; }
};
struct SecondChild : Father
{
bool shouldProcess() override { return true; }
}
答
有几种方法可以做到这一点。
typeid
和dynamic_cast<>
是做这件事的“官方方式”。
FirstChild *fptr = dynamic_cast<FirstChild>(myInstance);
if (fptr) {
// do something
} else {
SecondChild *cptr = dynamic_cast<SecondChild>(myInstance);
if(cptr) {
// do something else, and so on...
}
}
但是,这不是最优雅的方式来做到这一点。
另一种等效的方法是有一个“ID类型”,像枚举或类似。
但正如很多人所说,如果你需要知道什么类型,你可能会做错误的方式。
一个明显的选择是让对象执行特定的操作。假设您在activate()
函数中使用此代码。为什么不使用虚拟doAction()
?
class Father {
public:
virtual void doAction() = 0;
}
//...
myInstance->doAction();
有这种变化,使用不同的设计模式。但我想你明白了。
'dynamic_cast'也许?无论如何,这样做的需要表明你有严重的设计缺陷。 – user0042
如果你需要知道这种类型,你可能做错了。 – juanchopanza
这听起来像是你应该用多态和虚函数解决的问题。也许'dynamic_cast'。 – NathanOliver