我有一个类A和从它继承另一个类的类型,B.我重写接受类型A的对象作为参数的函数,因此我必须接受的A.不过,我稍后调用只有B有的函数,所以如果传递的对象不是B类,我想返回false而不继续。查找C中的对象++
什么是找出传递给我的函数的对象类型的最佳方法是什么?
我有一个类A和从它继承另一个类的类型,B.我重写接受类型A的对象作为参数的函数,因此我必须接受的A.不过,我稍后调用只有B有的函数,所以如果传递的对象不是B类,我想返回false而不继续。查找C中的对象++
什么是找出传递给我的函数的对象类型的最佳方法是什么?
的dynamic_cast应该做的伎俩
TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);
的dynamic_cast
关键词从一个指针或引用类型到另投下了一个基准,执行运行时检查,以确保投的有效性。
如果试图转换为指针类型,它是不是一个类型的实际对象的,演员的结果将是NULL。如果您尝试转换为引用不是实际对象类型的类型,则该转换将抛出异常。
确保有在基类中的至少一个虚拟功能进行dynamic_cast的工作。
这就是所谓的RTTI,但你几乎肯定要重新考虑你的设计在这里,因为找到的类型,做基于它特别的东西使你的代码更脆。
确实。不幸的是,我正在研究一个现有的项目,所以我无法真正改变设计,或者A类中的任何东西。 – lemnisca 2008-12-09 05:23:38
您是否在寻找dynamic_cast<B*>(pointer)
?
你的描述有点混乱。
一般来说,尽管一些C++实现有它的机制,但你不应该问这个类型。相反,您应该对指向A的指针执行dynamic_cast。这将会执行的是在运行时,将检查指向A的指针的实际内容。如果你有一个B,你会得到你的指针B.否则,你会得到一个异常或null。
可能嵌入到您的对象的ID的“标签”,并用它的类A的对象和类B.
的对象之间进行区分然而,这显示了在设计的一个缺陷。理想情况下,A中没有的B中的方法应该是A的一部分,但保留为空,B将覆盖它们。这消除了特定于类的代码,更符合OOP的精神。
正如其他人表示你可以使用dynamic_cast。但是通常使用dynamic_cast来找出你正在处理的派生类的类型,这表明了糟糕的设计。如果您重写了一个函数,该函数将A的指针作为参数,那么它应该能够使用A类本身的方法/数据,并且不应该依赖于类B的数据。在您的情况下,如果您不是重写确信你写的方法只适用于B类,那么你应该在B类中写一个新方法。
使用重载函数。不需要的dynamic_cast甚至RTTI支持:
class A {};
class B : public A {};
class Foo {
public:
void Bar(A& a) {
// do something
}
void Bar(B& b) {
Bar(static_cast<A&>(b));
// do B specific stuff
}
};
动态转换是最适合你的问题, 描述,但我只想补充一点,你可以找到类的类型有:
#include <typeinfo>
...
string s = typeid(YourClass).name()
因为你的类不是多态的。试试:
struct BaseClas { int base; virtual ~BaseClas(){} };
class Derived1 : public BaseClas { int derived1; };
现在BaseClas
是多态的。我将类更改为struct,因为默认情况下,结构的成员是公共的。
只要是完整的,我将建立蓄客Robocide的,并指出不使用名称()的typeid
可以单独使用:
#include <typeinfo>
#include <iostream>
using namespace std;
class A {
public:
virtual ~A() = default; // We're not polymorphic unless we
// have a virtual function.
};
class B : public A { } ;
class C : public A { } ;
int
main(int argc, char* argv[])
{
B b;
A& a = b;
cout << "a is B: " << boolalpha << (typeid(a) == typeid(B)) << endl;
cout << "a is C: " << boolalpha << (typeid(a) == typeid(C)) << endl;
cout << "b is B: " << boolalpha << (typeid(b) == typeid(B)) << endl;
cout << "b is A: " << boolalpha << (typeid(b) == typeid(A)) << endl;
cout << "b is C: " << boolalpha << (typeid(b) == typeid(C)) << endl;
}
输出:
a is B: true
a is C: false
b is B: true
b is A: false
b is C: false
如果您可以访问增强库,也许type_id_with_cvr()函数是你需要的,它可以是provide data type without removing const, volatile, & and && modifiers。这里是C++ 11中的一个简单例子:
#include <iostream>
#include <boost/type_index.hpp>
int a;
int& ff()
{
return a;
}
int main() {
ff() = 10;
using boost::typeindex::type_id_with_cvr;
std::cout << type_id_with_cvr<int&>().pretty_name() << std::endl;
std::cout << type_id_with_cvr<decltype(ff())>().pretty_name() << std::endl;
std::cout << typeid(ff()).name() << std::endl;
}
希望这是有用的。
你的意思是在基类中必须有一个虚函数才能使dynamic_cast工作。我认为这很重要,我只是猜测。 – GiCo 2015-08-19 08:20:37
确定发现它:运行时类型信息(RTTI)仅适用于多态的类,这意味着它们至少有一个虚拟方法。 dynamic_cast和typeid需要RTTI。 – GiCo 2015-08-19 08:54:23
如果它不可转换,不会抛出`dynamic_cast`?有没有办法做到这一点,而不产生投掷? – jww 2016-08-31 11:38:26