且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C++ 中的类型转换/强制转换混淆

更新时间:2021-10-12 05:52:05

转换 是将值转换为不同的类型.结果是目标类型的值,对于什么输出值来自什么输入(源类型)有规则.

Conversion is when a value is, um, converted to a different type. The result is a value of the target type, and there are rules for what output value results from what input (of the source type).

例如:

int i = 3;
unsigned int j;
j = i; // the value of "i" is converted to "unsigned int".

结果是 unsigned int 值等于 i modulo UINT_MAX+1,这个规则是语言的一部分.所以,在这种情况下,值(英文)仍然是3",但它是一个无符号 int 值 3,与有符号 int 值 3 有微妙的不同.

The result is the unsigned int value that is equal to i modulo UINT_MAX+1, and this rule is part of the language. So, in this case the value (in English) is still "3", but it's an unsigned int value of 3, which is subtly different from a signed int value of 3.

请注意,转换是自动发生的,我们只是在需要无符号 int 值的位置使用了一个有符号 int 值,并且语言定义了这意味着什么,而我们实际上并没有说我们正在转换.这就是所谓的隐式转换".

Note that conversion happened automatically, we just used a signed int value in a position where an unsigned int value is required, and the language defines what that means without us actually saying that we're converting. That's called an "implicit conversion".

强制转换"是显式转换.

例如:

unsigned int k = (unsigned int)i;
long l = long(i);
unsigned int m = static_cast<unsigned int>(i);

都是演员表.具体来说,根据标准5.4/2,k使用cast-expression,根据5.2.3/1,l使用一个等效的东西(除了我使用了不同的类型).m 使用类型转换运算符"(static_cast),但标准的其他部分也将其称为类型转换".

are all casts. Specifically, according to 5.4/2 of the standard, k uses a cast-expression, and according to 5.2.3/1, l uses an equivalent thing (except that I've used a different type). m uses a "type conversion operator" (static_cast), but other parts of the standard refer to those as "casts" too.

用户定义的类型可以定义转换函数",它提供了将类型转换为另一种类型的特定规则,并且单参数构造函数也用于转换:

User-defined types can define "conversion functions" which provide specific rules for converting your type to another type, and single-arg constructors are used in conversions too:

struct Foo {
    int a;
    Foo(int b) : a(b) {}                   // single-arg constructor
    Foo(int b, int c) : a(b+c) {}          // two-arg constructor
    operator float () { return float(a); } // conversion function
};

Foo f(3,4);              // two-arg constructor
f = static_cast<Foo>(4); // conversion: single-arg constructor is called
float g = f;             // conversion: conversion function is called