Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么使用静态_cast<;int>;(x) 而不是(int)x?_C++_Casting_Static Cast - Fatal编程技术网

C++ 为什么使用静态_cast<;int>;(x) 而不是(int)x?

C++ 为什么使用静态_cast<;int>;(x) 而不是(int)x?,c++,casting,static-cast,C++,Casting,Static Cast,我听说比起C风格或简单功能风格的转换,static\u cast功能应该更受欢迎。这是真的吗?为什么?static\u cast除了操作指向类的指针外,还可用于执行类中显式定义的转换,以及执行基本类型之间的标准转换: double d = 3.14159265; int i = static_cast<int>(d); double d=3.14159265; int i=静态(d); static\u cast意味着您不能意外地const\u cast或重新解释\u cas

我听说比起C风格或简单功能风格的转换,
static\u cast
功能应该更受欢迎。这是真的吗?为什么?

static\u cast除了操作指向类的指针外,还可用于执行类中显式定义的转换,以及执行基本类型之间的标准转换:

double d = 3.14159265;
int    i = static_cast<int>(d);
double d=3.14159265;
int i=静态(d);

static\u cast
意味着您不能意外地
const\u cast
重新解释\u cast
,这是一件好事。

这是关于您想要施加多少类型安全性的问题

当您编写
(bar)foo
(如果您没有提供类型转换运算符,这相当于
重新解释\u cast foo
)时,您告诉编译器忽略类型安全性,只需按照要求执行即可

当您编写
static\u cast foo
时,您要求编译器至少检查类型转换是否有意义,并且对于整型类型,插入一些转换代码


编辑2014-02-26


我在5年多前写下了这个答案,但我弄错了。(见评论)但它仍然获得了更多的选票

一个实用技巧:如果你打算整理项目,你可以在源代码中轻松搜索static\u cast关键字。

主要原因是经典的C cast没有区分我们所称的
static\u cast()
reinterpret\u cast()
const\u cast()
,和
dynamic\u cast()
。这四件事是完全不同的

static\u cast()
通常是安全的。语言中有一个有效的转换,或者有一个合适的构造函数使之成为可能。唯一有点冒险的时候是当你放弃继承类时;您必须确保该对象实际上是您声称的后代,方法是语言外部的(如对象中的标志)。只要检查结果(指针)或考虑到可能的异常(参考),则
动态\u cast()
是安全的

另一方面,
重新解释常量()
(或
常量()
)总是危险的。你告诉编译器:“相信我:我知道这看起来不像是一个
foo
(看起来好像它是不可变的),但它是”

第一个问题是,如果不查看大量分散的代码片段并了解所有规则,就几乎不可能判断C样式转换中会出现哪一个

让我们假设:

class CDerivedClass : public CMyBase {...};
class CMyOtherStuff {...} ;

CMyBase  *pSomething; // filled somewhere
现在,这两个函数的编译方式相同:

CDerivedClass *pMyObject;
pMyObject = static_cast<CDerivedClass*>(pSomething); // Safe; as long as we checked

pMyObject = (CDerivedClass*)(pSomething); // Same as static_cast<>
                                     // Safe; as long as we checked
                                     // but harder to read
CDerivedClass*pMyObject;
pMyObject=静态_转换(pSomething);//安全的;只要我们检查过
pMyObject=(CDerivedClass*)(pSomething);//与静态_cast相同
//安全的;只要我们检查过
//但更难阅读
但是,让我们看一下几乎相同的代码:

CMyOtherStuff *pOther;
pOther = static_cast<CMyOtherStuff*>(pSomething); // Compiler error: Can't convert

pOther = (CMyOtherStuff*)(pSomething);            // No compiler error.
                                                  // Same as reinterpret_cast<>
                                                  // and it's wrong!!!
CMyOtherStuff*pOther;
pOther=静态施法(pSomething);//编译器错误:无法转换
pOther=(CMyOtherStuff*)(pSomething);//没有编译器错误。
//与重新解释_cast相同
//这是错误的!!!
正如您所看到的,如果不了解所有涉及的类,就很难区分这两种情况


第二个问题是C样式转换太难定位。在复杂表达式中,很难看到C样式转换。几乎不可能编写一个自动化工具,它需要定位C风格的铸件(例如搜索工具),而不需要完全的C++编译器前端。另一方面,很容易搜索“StasyStudio

”,问题不仅仅是使用枯萎的STATICE-CAST或C型的铸造,因为在使用C样式的铸件时会发生不同的事情。C++的铸造操作符旨在使这些操作更加明确。 在曲面上,静态类型转换和C样式转换显示为相同的内容,例如,将一个值转换为另一个值时:

int i;
double d = (double)i;                  //C-style cast
double d2 = static_cast<double>( i );  //C++ cast
inti;
双d=(双)i;//C样式转换
double d2=static_cast(i);//C++cast
这两种方法都将整数值转换为双精度。但是,当使用指针时,事情会变得更复杂。一些示例:

class A {};
class B : public A {};

A* a = new B;
B* b = (B*)a;                                  //(1) what is this supposed to do?

char* c = (char*)new int( 5 );                 //(2) that weird?
char* c1 = static_cast<char*>( new int( 5 ) ); //(3) compile time error
A类{};
B类:公共A{};
A*A=新的B;
B*B=(B*)a;//(1)这应该做什么?
char*c=(char*)新的int(5);/(2)那奇怪吗?
char*c1=static_cast(新int(5));/(3)编译时错误
在这个例子中(1)可能是可以的,因为A指向的对象实际上是B的实例。但是如果你在代码中不知道A实际指向的是什么呢?(2)可能是完全合法的(你只想看整数的一个字节),但也可能是个错误,在这种情况下,错误会很好,如(3)C++的C铸造运算符旨在通过提供编译时间或运行时错误,在代码中暴露这些问题。

因此,对于严格的“值转换”,您可以使用静态转换。如果您想要运行时多态性转换指针,请使用动态转换。如果您真的想忘记类型,可以使用ReintRecpret转换。要将const抛出窗口,有const转换


<>他们只是让代码更显,这样看起来你知道你在做什么。

< P> C风格的转换在一个代码块中很容易被忽略。C++风格的转换不仅仅是更好的实践;它们提供了更大的灵活性。 reinterpret_cast允许整数到指针类型的转换,但如果使用不当,则可能不安全

static_cast为数字类型提供了良好的转换,例如从as enum到int或int到float或任何您确信类型的数据类型。它不执行任何运行时检查<
class A {};
class B : public A {};

A* a = new B;
B* b = (B*)a;                                  //(1) what is this supposed to do?

char* c = (char*)new int( 5 );                 //(2) that weird?
char* c1 = static_cast<char*>( new int( 5 ) ); //(3) compile time error
char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes
*p = 5; // run-time error: stack corruption
int *q = static_cast<int*>(&c); // compile-time error