`
cwqcwk1
  • 浏览: 86961 次
文章分类
社区版块
存档分类
最新评论

浅谈C++的类型转换

 
阅读更多

C++是强类型语言,也就是说,变量在使用前就要声明数据类型,不同数据类型分配的内存空间大小也是不同,在转换类型时要注意这个问题,防止数据丢失或越界溢出。文章将简单讨论一下C++的类型转换。

C++从C发展而来,也继承两种C风格的转换:隐式转换和显式转换。

隐式转换
隐式转换是指由编译系统自动进行,不需要人工干预的类型转换,例如:

short a = 2000;
int b;
b = a;
隐式转换,也包括构造函数和运算符的转换,例如:
class A {};
class B {
public: 
   B (A a) {}
};

A a;
B b = a;
显式转换

和隐式转换相反,显式转换要利用强制类型转换运算符进行转换,例如:

double x = 10.3;
int y;
y = int (x);    // 函数式写法
y = (int) x;    // C风格写法

以上类型转换已经满足了基本类型的转换了。但是如果想转换类和指针,有时代码可以编译,在运行过程中会出错。例如:
#include <iostream>

class CDummy {
    float i,j;
public:
    CDummy () { i=1; j=1; }
};

class CAddition {
    int x,y;
public:
    CAddition () { x=1; y=1; }
    int result() { return x+y;}
};

int main () {
  CDummy d;
  CAddition * padd;
  padd = (CAddition*) &d;
  std::cout << padd->result();
  return 0;
}
这段代码会在运行期出错,在执行padd->result()时发生异常,有些编译器会异常退出。
传统明确的类型转换,可以转换成任何其他指针类型任何指针,它们指向的类型无关。在随后的调用成员的结果,会产生一个运行时错误或意外的结果。
/********  无情的分割线 ********* / 
  作者:没有开花的树 
  博客:blog.csdn.net/mycwq 
/ *******   无情的copy  *********/  

C++标准转换运算符
传统的类和指针的类型转换方式很不安全,可能会在运行时异常退出,标准C++ 提供了四个转换运算符:dynamic_cast、reinterpret_cast、static_cast、 const_cast
dynamic_cast <new_type> (expression)
reinterpret_cast <new_type> (expression)
static_cast <new_type> (expression)
const_cast <new_type> (expression)

dynamic_cast
dynamic_cast只能用于指针和引用的对象。其目的是确保类型转换的结果是一个有效的完成所请求的类的对象,所以当我们从一个类转换到这个类的父类,dynamic_cast总是可以成功。dynamic_cast可以转换NULL指针为不相关的类,也可以任何类型的指针为void指针。
class CBase { };
class CDerived: public CBase { };
CBase b;
CDerived d;

CBase* pb = dynamic_cast<CBase*>(&d);        // 子类转父类,正确
CDerived* pd = dynamic_cast<CDerived*>(&b);  // 父类转子类,错误
当新的类型不是被转换的类型的父类,dynamic_cast无法完成指针的转换,返回NULL。当dynamic_cast转换引用类型时,遇到失败会抛出Bad_cast 异常。


static_cast
static_cast可以执行相关的类的指针之间的转换,可以在子类和父类之间相互转换,但父类指针转成子类指针是不安全的。static_cast没有在运行时进行安全检查,因此我们要先确保转换是安全的。另一方面,static_cast对比dynamic_cast少了在类型安全检查的开销。
class CBase {};
class CDerived: public CBase {};
CBase * a = new CBase;
CDerived * b = static_cast<CDerived*>(a);
上述代码是合法的,b指向一个不完整的对象,可能在运行期导致错误。
static_cast也可以用来执行任何其他非指针的转换,如基本类型enum, struct, int, char, float等之间的标准转换:
double d = 3.14159265;
int i = static_cast<int>(d); 
void* p = static_cast<void*>(&i); //任意类型转换成void类型


reinterpret_cast
reinterpret_cast转换成任何其他指针类型,甚至无关的类,任何指针类型。操作的结果是重新解释类型,但没有进行二进制的转换。所有的指针转换是允许的:不管是指针指向的内容还是指针本身的类型。
class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B*>(a)

reinterpret_cast还可以用来转换函数指针类型,例如:

typedef void(*Func)();                 // 声明一种函数指针定义,返回void
Func pFunc;                            // 定义FuncPtr类型的数组

pFunc = &test;                         // 编译错误!类型不匹配
pFunc = reinterpret_cast<Func>(&test); // 编译成功!转换函数指针类型

const_cast
const_cast用于操纵对象的常量性,去掉类型的const或volatile属性。
#include <iostream>

void print (char * str){
  std::cout << str ;
}

int main () {
  const char* c = "hello world";
  print ( const_cast<char *> (c) );
  return 0;
}

参考:

http://blog.csdn.net/mycwq/article/details/17300973
http://www.cnblogs.com/ggjucheng/archive/2012/01/04/2311650.html
http://www.cplusplus.com/doc/tutorial/typecasting/

分享到:
评论

相关推荐

    浅谈C++中强制类型转换函数

    "C++强制类型转换函数详解" C++中强制类型转换函数是指使用强制类型转换操作符来实现类型转换的过程。C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用,即const_cast、static_cast、dynamic_cast和...

    浅谈C++的语句语法与强制数据类型转换

    在C++编程语言中,语句语法和强制数据类型转换是至关重要的概念,对于初学者来说,理解这些基础内容是掌握C++的关键。本文将详细阐述这两个主题。 首先,我们来看C++的语句语法。C++程序由一系列的程序单位构成,每...

    浅谈C++类型转化(运算符重载函数)和基本运算符重载(自增自减)

    在C++提供类型转换函数(type conversion function)来解决这个问题。类型转换函数的作用是将一个类的对象转换成另一类型的数据。 类型转换函数的一般形式为: operator 类型名( ){ 实现转换的语句 } 下面是简单实现...

    浅谈C++ IO流

    "浅谈C++ IO流" C++ IO流是一种抽象概念,它代表了数据的无结构化传递。在计算机科学中,输入输出(IO)是指计算机同任何外部设备之间的数据传递。常见的输入输出设备有文件、键盘、打印机、屏幕等。数据可以按记录...

    浅谈c++ 预处理器

    浅谈 C++ 预处理器 C++ 预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理。所有的预处理器指令都是以井号(#)开头,只有空格字符可以出现在预处理指令之前。预处理指令不是 C++ 语句,所以它们不会...

    浅谈C++ Explicit Constructors(显式构造函数)

    C++中的显式构造函数(Explicit Constructors)是编程实践中一个重要的概念,主要用来控制类对象的隐式类型转换。在C++中,如果一个类有一个只接受一个参数的构造函数,那么这个构造函数可以被用来进行隐式类型转换...

    浅谈C++的几种从键盘输入方式

    不管数据类型是什么,输入一开始都是字符数据,然后cin对象负责将数据转换成其他类型 例如 string name; std::cin&gt;&gt;name; std::cout&lt;&lt;name; 当你输入Michael Jackon时,通运行程序你会发现name只存储了...

    浅谈c++ 字符类型总结区别wchar_t,char,WCHAR

    在C++编程中,字符类型是数据表示的重要组成部分,特别是在处理文本字符串时。本文将深入探讨三种常见的字符类型:`char`、`wchar_t`和`WCHAR`,以及它们之间的区别和相互转换。 1. `char`类型: `char`是C++中的...

    浅谈C++ 基类指针和子类指针的相互赋值

    总结来说,C++中的基类指针和子类指针的相互赋值体现了面向对象编程中的多态性和类型转换原则。向上转型(基类指针指向子类对象)是安全的,不需要显式转换;而向下转型(子类指针指向基类对象)则需要显式类型转换...

    浅谈C++左值引用和右值引用

    但是,右值引用不能直接绑定到左值,除非通过`std::move`函数,该函数可以将左值转换为对应的右值引用类型,如`int &&r6 = std::move(r2);`。 左值引用和右值引用的一个关键区别在于,左值引用通常表示对象的身份,...

    浅谈C++中char型变量的地址输出

    浅谈C++中char型变量的地址输出 在C++中,输出变量的地址是一种常见的操作,但是在输出char型变量的地址时,需要注意一些特殊情况。在这篇文章中,我们将探讨char型变量的地址输出,了解为什么char型变量的地址输出...

    浅谈C++ 虚函数

    此外,vtable中索引为-1的位置通常用于动态类型转换的相关信息。 虚函数调用的过程依赖于vptr和vtable。当我们通过基类指针调用虚函数时,如`pBase-&gt;VFun1()`,实际上会通过vptr找到对应的vtable,然后从vtable中...

    浅谈C++虚重载操作符 virtual operator= 的使用方法

    综上所述,`virtual operator=`是C++中实现多态赋值的重要工具,它的使用需要结合派生类的具体需求,正确处理参数类型、返回类型以及拷贝语义等问题,以确保代码的正确性和高效性。在设计类层次结构时,理解并熟练...

    浅谈c++的编译和运行

    C++是一种强大的、通用的编程语言,以其高效性、灵活性和面向对象的特性而闻名。在深入探讨C++的编译和运行之前,先要理解编程语言的基本工作流程。编程语言是人类可读的代码,但计算机并不能直接理解。因此,我们...

    浅谈数位类统计问题

    ### 浅谈数位类统计问题 在信息学竞赛领域,数位类统计问题是一类常见而又富有挑战性的问题类型,它们通常涉及到对特定区间内的数进行基于数位特性的统计分析。这类问题不仅考验参赛者的数学逻辑能力,还要求掌握...

    浅谈Python程序与C++程序的联合使用

    SWIG特别适合处理复杂的数据类型转换和大型C++项目。 6. 利用Python/C++混合编程框架:有一些框架允许将Python代码和C++代码混合在一起执行,如Boost.Python。这些框架为开发者提供了更加方便的接口,使得C++代码的...

Global site tag (gtag.js) - Google Analytics