我想知道什么是静态和动态类型检查以及它们之间的差异。
答案 0 :(得分:17)
静态类型检查意味着在编译时进行类型检查。在这种情况下,运行时不会使用任何类型信息。
在运行时使用类型信息时会发生动态类型检查。 C ++使用一种称为RTTI(运行时类型信息)的机制来实现它。使用RTTI的最常见示例是dynamic_cast运算符,它允许向下转换多态类型:
// assuming that Circle derives from Shape...
Shape *shape = new Circle(50);
Circle *circle = dynamic_cast<Circle*> shape;
此外,您可以使用typeid运算符来查找对象的运行时类型。例如,您可以使用它来检查示例中的形状是圆形还是矩形。这是一些further information。
答案 1 :(得分:4)
C ++对动态类型检查的支持很少,一个是通过dynamic_cast,另一个是通过type id。只有在编译器中启用了RTTI支持时才能使用它们。
TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);
dynamic_cast关键字将数据从一个指针或引用类型转换为另一个,执行运行时检查以确保转换的有效性。
如果您尝试转换为指向不是实际对象类型的类型的指针,则转换的结果将为NULL。如果您尝试强制转换为引用不是实际对象类型的类型,则强制转换将抛出bad_cast异常。
确保Base类中至少有一个虚拟函数可以使动态域工作。
// expre_typeid_Operator.cpp
// compile with: /GR /EHsc
#include <iostream>
#include <typeinfo.h>
class Base {
public:
virtual void vvfunc() {}
};
class Derived : public Base {};
using namespace std;
int main() {
Derived* pd = new Derived;
Base* pb = pd;
cout << typeid( pb ).name() << endl; //prints "class Base *"
cout << typeid( *pb ).name() << endl; //prints "class Derived"
cout << typeid( pd ).name() << endl; //prints "class Derived *"
cout << typeid( *pd ).name() << endl; //prints "class Derived"
delete pd;
}
答案 2 :(得分:2)
C ++中有多种类型的强制转换。
最常见的是使用static_cast将变量从一种指针转换为另一种指针。但是,您也可以使用dynamic_cast,它将检查(在运行时)指针的类型是否正确。使用dynamic_cast时,如果指针不是正确类型,则在运行时,它将返回0。
// Assume these classes exist
// class A
// class B
// class C : B
C* c = new C();
A* a = new A();
B* b = static_cast<B*>(a); // this will work!
b = dynamic_cast<B*>(a); // b == NULL
b = dynamic_cast<B*>(c); // b is valid
答案 3 :(得分:2)
假设你有:
class A {};
class B:A {};
A* a = new B();
B* b = new B();
对于静态类型,您可以查看变量的声明方式。
A* a = ...
B* b = ...
因此a
的静态类型为A*
(换句话说,*a
的静态类型为A
)。
b
的静态类型为B*
(换句话说,*b
的静态类型为B
)。
请注意a
和b
有一个静态类型,由它的声明修复 - 无论你输入什么都没关系,它们将保持相同的静态类型。 (“静态”的意思是“不变”)。
对于动态类型,您现在可以查看变量中发生的情况。
a = new B();
b = new B();
因此a
和b
的动态类型都是B*
(换句话说,*a
和*b
的动态类型是两个B
)。
请注意,动态类型可以更改 - 如果您执行了a = new A()
,则动态类型a
只会更改为A*
。有时您不知道动态类型是什么 - 例如如果您执行a = somefunc()
,则a
可能包含动态类型A*
,B*
甚至C*
(如果您未看到某些代码定义C
}作为A
或B
)的子类。
如果A
上有virtual
方法,那么您可以使用dynamic_cast
来确定动态类型是什么。 (通常,如果您使用此类代码,则希望能够执行delete a
;要使其工作A
,析构函数必须为virtual
。并且{ {1}}析构函数虚拟就足以让A
工作了。)
答案 4 :(得分:0)
静态类型检查是在编译时完成的类型检查。这是C ++唯一的类型检查类型。动态类型检查是在运行时完成的类型检查。这通常出现在动态解释语言中,但在编译语言中不太常见。最后我查了一下,C ++没有做任何动态类型检查。
编辑:显然我已经过时了。请参阅下面的Reed评论。