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

C++ C+中的静态与动态类型检查+;,c++,C++,我想知道什么是静态和动态类型检查以及它们之间的区别。静态类型检查是在编译时完成的类型检查。这是C++唯一类型的检查类型。动态类型检查是在运行时完成的类型检查。这通常出现在动态解释语言中,但在编译语言中不太常见。上次我检查过,C++没有做任何类型的动态类型检查。 编辑:显然我已经过时了。请参阅下面的Reed评论。静态类型检查意味着类型检查发生在编译时。在这种情况下,运行时不使用类型信息 在运行时使用类型信息时会发生动态类型检查。C++使用一种机制,称为RTTI(运行时类型信息)来实现这个。使用RT

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

静态类型检查是在编译时完成的类型检查。这是C++唯一类型的检查类型。动态类型检查是在运行时完成的类型检查。这通常出现在动态解释语言中,但在编译语言中不太常见。上次我检查过,C++没有做任何类型的动态类型检查。
编辑:显然我已经过时了。请参阅下面的Reed评论。

静态类型检查意味着类型检查发生在编译时。在这种情况下,运行时不使用类型信息

在运行时使用类型信息时会发生动态类型检查。C++使用一种机制,称为RTTI(运行时类型信息)来实现这个。使用RTTI的最常见示例是dynamic_cast操作符,它允许多态类型的向下转换:

// assuming that Circle derives from Shape...
Shape *shape = new Circle(50);
Circle *circle = dynamic_cast<Circle*> shape;
//假设圆来自形状。。。
形状*形状=新圆(50);
圆*圆=动态_铸造形状;

此外,您可以使用typeid操作符来了解对象的运行时类型。例如,您可以使用它来检查示例中的形状是圆形还是矩形。这里有一些。

< P> C++中有多种类型的可供选择。 最常见的方法是将变量从一种指针类型强制转换为另一种类型。但是,您也可以使用,它将检查以确保(在运行时)指针的类型正确。使用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
//假设这些类存在
//甲级
//B类
//丙类:乙类
C*C=新的C();
A*A=新的A();
B*B=静态(a);//这会有用的!
b=动态(a);//b==NULL
b=动态(c);//b是有效的

C++很少支持动态类型检查,一个是通过,另一个是通过。只有在编译器中启用RTTI支持时,才能使用这两种方法

TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);
类型和动态类型转换(对象);
类型*动态_转换(对象);
dynamic_cast关键字将数据从一个指针或引用类型强制转换为另一个指针或引用类型,执行运行时检查以确保强制转换的有效性

如果您试图强制转换为指向不是实际对象类型的类型的指针,则强制转换的结果将为NULL。如果您试图强制转换引用的类型不是实际对象的类型,则强制转换将引发错误的\u强制转换异常

确保基类中至少有一个虚拟函数可以使DynamicCast工作。

// 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;
}
//expre\u typeid\u Operator.cpp
//使用:/GR/EHsc编译
#包括
#包括
阶级基础{
公众:
虚拟void vvfunc(){}
};
派生类:公共基{};
使用名称空间std;
int main(){
衍生*pd=新衍生;
碱基*pb=pd;
不能假设您有:

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
有一个由其声明固定的静态类型-无论您在其中添加了什么,它们都将保持相同的静态类型。(“static”表示“不变”)


对于动态类型,您可以查看变量中现在发生了什么

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\u cast
来确定动态类型是什么。(通常,如果您正在使用这种类型的代码,您希望能够执行
删除
;要使其工作
a
的析构函数必须是
虚拟的
。而使
a
的析构函数虚拟就足以让
动态强制转换
工作)在C++中,动态//P> DyjixSCAST,并且在许多C++运行时运行时类型检查。“b*b= StasyType(a);//这将有效!”:你不应该把这个评论说成“这将编译,你得到非空指针,但它不一定会起作用!”?我认为实际上,静态_cast只适用于相关类型,并且会拒绝编译,在这种情况下需要重新解释_cast。这些示例在我看来都是一团糟。stackoverflow的目标是成为所有编程知识的存储库,即使它存在于其他地方。我知道它在google上的某个地方,但在这里你可以得到多个def帮助您以更清晰的方式理解way@jpinto3912rkb是正确的。你不应该阻止人们问这样的问题。如果它在堆栈溢出的目标范围内,你无权评论或反对…值得注意的是,在上面的简单示例中,静态\u转换是完全有效的。只有在以下情况下才应使用动态\u转换您不确定形状是否为Circle类型,在这种情况下,dynamic_cast将返回NULL(如果您正在转换引用,则会引发异常)。您没有解决静态类型检查问题