C++类型转换

简介: C++类型转换

C++类型转换


类型转换是将一种数据类型转换成另外一种数据类型。例如将一个整形数据赋值给一个浮点类型变量,编译器会暗中将其转换成浮点类型。转换是非常有用的,但是它也会带来一些问题,比如在转换指针时,我们很可能将其转换成一个比它更大的类型,但这可能破坏其他的数据。应该小心类型转换,因为转换也就相当于让编译器 在这个位置不进行类型检查,把它看做其他类型。一般情况下,尽量少用类型转换,除非用来解决非常特殊的问题。


无论什么原因,一个程序如果有太多的类型转换的话,程序都是值得怀疑的。


标准C++提供了一个显示的转换语法,来代替C风格的类型转换。使用C风格的强制转换可以把想要的任何东西转换成我们需要的类型。那为什么还需要一个新的C++类型的强制转换关系呢?新类型的强制转换可以提供更好的转换过程,允许控制各种不同类型的强制转换。C++风格的强制转换的好处就是他们能够更加清晰的表明它们是要干什么。程序员只需要看一眼代码就知道这个转换的目的。


静态类型转换(static_cast)


  • 用于类层次结构中基类(父类)和派生类(子类)之间指针的引用和转换。


进行上行转换(把派生类的指针或者引用转换成基类表示是安全的),因为操作空间不会越界;

进行下行黄钻换(把基类指针或者引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。


  • 用于基本数据类型之间的转换


如把int转换成char,把char转换成int。这种转换的安全性也需要开发人员来保证

#include <iostream>
#include <string>
#include <iostream>
using namespace std;
class Base
{
public:
};
class Derive : public Base
{
public:
};
class Other
{
public:
};
void test()
{
    char ch = 'a';
    cout << static_cast<int> (ch) << endl;
    Base *b = new Base;
    Derive *d = new Derive;
    Other *o = new Other;
    Base *dd = static_cast<Derive *>(d);
//    Base *cc = static_cast<Other *>(d);
}
int main(int argc, char* argv[])
{
    test();
    return 0;
}

注意: 静态类型转换不能作用于不想关的类型转换。


动态类型转换(dynamic_cast)


  • 主要用于类层次间的上行转换和下行转换;


在进行类层次间上行转换时,dynamic_cast和static_cast是一样的;

在进行下行转换时,dynamic_cast具有类型检查功能,比static_cast更安全;

#include <iostream>
#include <string>
#include <iostream>
using namespace std;
class Base
{
public:
};
class Derive : public Base
{
public:
};
class Derive2 : public Base
{
public:
};
void test()
{
    char ch = 'a';
    cout << static_cast<int> (ch) << endl;
    Base *b = new Base;
    Derive *d = new Derive;
    Derive2 *o = new Derive2;
    Base *dd = dynamic_cast<Derive *>(d);
//    Derive2 *dd = dynamic_cast<Derive2 *>(b);
//    Derive2 *cc = dynamic_cast<Derive2 *>(d);
}
int main(int argc, char* argv[])
{
    test();
    return 0;
}

注意: 不安全的转换时无法转换,且不支持没有关系的类型进行转换。因此正常使用动态类型转换去进行类型转换。


常量转换(const_cast)


  • 用来修改类型的const属性。


常量指针被转换成非常量指针,并且仍然指向原来的对象:常量引用被转换成非常量引用,并且仍然指向原来的对象

#include <iostream>
#include <string>
#include <iostream>
using namespace std;
void test()
{
    // 将const int 转成int
    const int *p = nullptr;
    int *pp = const_cast<int *>(p);
    
    int *p1 = nullptr;
    const int *pp1= p1;

    const int a = 10;
    int *b = const_cast<int *>(a);
}
int main(int argc, char* argv[])
{
    test();
    return 0;
}

注意: 不能直接对非指针和非引用的变量进行const类型转换


重新解释转换(reinterpret_cast)


这个是最不安全的一种转换机制,最有可能出问题。主要用于将一种数据类型从一种类型转换成为另外一种类型。不关注转换数据之间的数据类型。

#include <iostream>
#include <string>
#include <iostream>
using namespace std;
void test()
{
    // 将const int 转成int
    const int *p = nullptr;
    int *pp = const_cast<int *>(p);
    int a = reinterpret_cast<int>(pp);
}
int main(int argc, char* argv[])
{
    test();
    return 0;
}
目录
相关文章
|
7月前
|
安全 编译器 程序员
【C++】C++的类型转换
【C++】C++的类型转换
|
7月前
|
设计模式 安全 算法
【C/C++ 类型转换 】深入理解C++向上转型:从基础到应用
【C/C++ 类型转换 】深入理解C++向上转型:从基础到应用
232 0
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
103 5
|
2月前
|
编译器 C语言 C++
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
30 1
|
2月前
|
存储 编译器 数据安全/隐私保护
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解2
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
44 3
|
2月前
|
编译器 C++
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解1
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
55 3
|
7月前
|
存储 安全 编译器
C++:现代类型转换
C++:现代类型转换
57 5
|
2月前
|
C++
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
29 0
|
5月前
|
存储 安全 编译器
【C++11】类型转换
【C++11】类型转换
40 0
|
5月前
|
安全 程序员 编译器
C++一分钟之-C++中的类型转换
【7月更文挑战第8天】C++中的类型转换涉及隐式和显式操作,隐式转换如从`int`到`double`是自动的,但可能导致数据丢失。显式转换包括`static_cast`, `dynamic_cast`, `const_cast`, `reinterpret_cast`,以及转换构造函数。要避免数据丢失、类型不匹配和运行时错误,需谨慎使用显式转换并检查结果。过度使用`reinterpret_cast`应避免。理解这些转换有助于编写更安全的代码。
49 0