C ++中的静态与动态类型检查

时间:2009-08-28 15:20:52

标签: c++

我想知道什么是静态和动态类型检查以及它们之间的差异。

5 个答案:

答案 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)。

请注意ab有一个静态类型,由它的声明修复 - 无论你输入什么都没关系,它们将保持相同的静态类型。 (“静态”的意思是“不变”)。


对于动态类型,您现在可以查看变量中发生的情况。

a = new B();
b = new B();

因此ab的动态类型都是B*(换句话说,*a*b的动态类型是两个B)。

请注意,动态类型可以更改 - 如果您执行了a = new A(),则动态类型a只会更改为A*。有时您不知道动态类型是什么 - 例如如果您执行a = somefunc(),则a可能包含动态类型A*B*甚至C*(如果您未看到某些代码定义C }作为AB)的子类。

如果A上有virtual方法,那么您可以使用dynamic_cast来确定动态类型是什么。 (通常,如果您使用此类代码,则希望能够执行delete a;要使其工作A,析构函数必须为virtual。并且{ {1}}析构函数虚拟就足以让A工作了。)

答案 4 :(得分:0)

静态类型检查是在编译时完成的类型检查。这是C ++唯一的类型检查类型。动态类型检查是在运行时完成的类型检查。这通常出现在动态解释语言中,但在编译语言中不太常见。最后我查了一下,C ++没有做任何动态类型检查。

编辑:显然我已经过时了。请参阅下面的Reed评论。