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

13

什么是类型转换(Type Conversion),什么是类型强制转换(Type Casting)

何时应该使用它们?

详细信息:如果这是一个明显的问题,我很抱歉;我是C++的新手,来自Ruby背景,并习惯于to_sto_i等等。

5个回答

18

转换是将一个值转换为不同类型的过程。结果是目标类型的值,并且有规则来确定源类型的输入对应哪种输出值。

例如:

int i = 3;
unsigned int j;
j = i; // the value of "i" is converted to "unsigned int".
结果是一个无符号整数值,该值等于 i 对 UINT_MAX+1 取模,而这个规则是语言的一部分。所以,在这种情况下,值仍然是 "3",但它是一个无符号整数值为 3,与有符号整数值 3 稍有不同。
请注意,这种转换是自动发生的,我们只是在需要无符号整数值的位置使用了有符号整数值,而语言定义了其含义,而无需实际说明我们正在进行转换。这被称为“隐式转换”。
"强制转换"是显式转换。
例如:
unsigned int k = (unsigned int)i;
long l = long(i);
unsigned int m = static_cast<unsigned int>(i);

这些都是类型转换。根据标准的5.4/2,k 使用了一个强制类型转换表达式,而根据5.2.3/1,l使用相同的东西(只是我使用了不同的类型)。m使用了一个"类型转换运算符" (static_cast),但标准的其他部分也将其称为"转换"。

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

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

3
经典强制类型转换(类似于C中的`(Bar)foo`,在C++中使用`reinterpret_cast<>`),是指假定变量的实际内存内容是不同类型变量的情况。类型转换(例如Boost的`lexical_cast<>`或其他用户定义的转换函数)则是执行一些逻辑来实际地将一个变量从一种类型转换为另一种类型,例如将整数转换为字符串,其中一些代码运行以从给定的整数逻辑地形成字符串。
还有静态转换和动态转换,用于继承中,例如强制在子类类型上使用父类成员函数(`dynamic_cast<>`),或者反过来(`static_cast<>`)。 静态转换还允许您执行通常发生的“隐式”类型转换,例如:
```c++ float f = 3.14; int i = f; //通过舍弃小数部分将浮点数转换为整数 ```
可以重写为:
```c++ float f = 3.14; int i = static_cast(f); //相同的操作 ```

2
+1,但应注意这个术语并非严格遵循。考虑int i; float f = static_cast<float>(i) - 按照您的逻辑(我也同意),这是一种转换,而不是一种强制类型转换。C++仍然使用static_cast(我知道这里可以使用隐式转换)。换句话说,您给出了两个术语最有意义的语义区别。但C++并没有遵循这种区别。 - Konrad Rudolph
1
编辑以澄清一些事情,希望我没有传播错误信息。 - Ken Simon
1
你似乎在说 cast-expression (5.4/2) 不是一个 cast,而是一种转换。这可能是针对编程语言的“cast”与“conversion”的有用定义,但它不是 C++ 标准中使用“cast”的定义。 - Steve Jessop

2
在C++中,任何表达式都有一个类型。当您在需要另一种类型(比如类型D)的值的上下文中使用一个类型为S的表达式时,编译器会尝试将表达式从类型S转换为类型D。如果这样的隐式转换不存在,则会导致错误。类型转换这个词不是标准用语,但与转换相同。
例如:
void f(int x){}

char c; 

f(c); //c is converted from char to int.

这些转换是有等级的,你可以搜索“促销 vs 转化率”以了解更多细节。

C++中有5个显式类型转换运算符:static_castconst_castreinterpret_castdynamic_cast,还有C风格转换


哇,谢谢大家,我没想到会这么快得到这么好的答案,感谢! - Ell
2
@Ell:C++标签很繁忙 :) - Armen Tsirunyan

2

类型转换是指将一个类型转换为另一种类型,例如将字符串转换为整数,反之亦然。而类型转换是指实际内存内容不改变,但编译器以不同的方式解释它。


1
类型转换表示您以不同的方式处理内存块。
int i = 10;
int* ip = &i;
char* cp = reinterpret_cast<char*>(ip);
if ( *cp == 10 )  // Here, you are treating memory that was declared
{                 // as int to be char.
}

类型转换表示将一个值从一种类型转换为另一种类型。
char c = 'A';
int i = c;  // This coverts a char to an int.
            // Memory used for c is independent of memory
            // used for i.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接