C++ 类型转换

1. 隐式转换(implicit)

  • 数值类型

a.低字节类型向高字节类型转换(正常转换)

short a = 20;
int b = a;

b.高字节向低字节类型转换(可能会导致数据丢失并且编译器报警告

double a = 10.2;
float b = a;

gcc -Wconversion -o test test.cxx

warning: conversion to 'int' alters 'double' constant value.

  • 指针转换
a. Null pointer 能够被转换成任何类型的pointer;
b .任何类型的pointer都能被转换成void pointer;
c. pointer能够向上转换成base class pointer;

  • 类(class)

a. Single-argument constructor:使用某对象去初始化另一对象;
b. Assignment operator: 对象赋值;
c. Type-cast operator: 借助于operator关键字进行转换。
// implicit conversion of classes:
#include <iostream>
using namespace std;

class A {};

class B {
public:
  // conversion from A (constructor):
  B (const A& x) {}
  // conversion from A (assignment):
  B& operator= (const A& x) {return *this;}
  // conversion to A (type-cast operator)
  operator A() {return A();}
};

int main ()
{
  A foo;
  B bar = foo;    // calls constructor
  bar = foo;      // calls assignment
  foo = bar;      // calls type-cast operator
  return 0;
}
d. explicit 关键字可禁止构造函数参数进行隐式转换
#include <iostream>
using namespace std;

class A {};

class B {
public:
  explicit B (const A& x) {}
  B& operator= (const A& x) {return *this;}
  operator A() {return A();}
};

void fn (B x) {}

int main ()
{
  A foo;
  B bar (foo);
  bar = foo;
  foo = bar;
  
//  fn (foo);  // not allowed for explicit ctor.
  fn (bar);  

  return 0;
}

2.显示转换(Explicit)

  • 强制类型转换(type-casting)
double x = 10.3;
int y;
y = int (x);    // functional notation
y = (int) x;    // c-like cast notation
没有限制的强制类型转换可能会造成运行时错误或者其他一些意想不到的错误。
#include <iostream>
using namespace std;

class Dummy {
    double i,j;
};

class Addition {
    int x,y;
  public:
    Addition (int a, int b) { x=a; y=b; }
    int result() { return x+y;}
};

int main () {
  Dummy d;
  Addition * padd;
  padd = (Addition*) &d;
  cout << padd->result();
  return 0;
}
  • dynamic_cast<new_type>(expression)
dynamic_cast只能用于类指针和类引用之间的转换,它进行类型安全的检测以确保转换结果的正确性。
a. 向上转换(将子类指针转换成父类指针)
b. 向下转换(将父类指针转换成子类指针),条件只有父类指针指向的是子类对象的时候转换才能成功;
c. 它还可以用来null pointer和一般指针的转换。
#include <iostream>
#include <exception>
using namespace std;

class Base { virtual void dummy() {} };
class Derived: public Base { int a; };

int main () {
  try {
    Base * pba = new Derived;
    Base * pbb = new Base;
    Derived * pd;

    pd = dynamic_cast<Derived*>(pba);
    if (pd==0) cout << "Null pointer on first type-cast.\n";

    pd = dynamic_cast<Derived*>(pbb);
    if (pd==0) cout << "Null pointer on second type-cast.\n";

  } catch (exception& e) {cout << "Exception: " << e.what();}
  return 0;
}
第一个转换从pba转到pd是可以的,而第二个转换则返回的是null. (dynamic_cast 用于指针时,转换失败返回null,用于引用时,转换失败抛出异常。)
  • static_cast<new type>(expression)
a. 相关类指针转换,向上向下转换均可以,但是不进行类型检查,可能会造成运行时错误;
class A { /* ... */ };
class B { /* ... */ };
A * a = new A;
B * b = reinterpret_cast<B*>(a);
b.可以进行数值转换
float fv = 10.1;
int iv = 21;
cout << static_cast<int>(fv) <<endl;
cout << static_cast<double>(iv) <<endl;
c. 不能进行不相关指针类型的转换
int iv = 10;
double* pd = static_cast<double*>(&iv);//error, can not convert from int* to double *

class a {/*  */};
class b {/* */};

b* pb = new b;
a* pa = static_cast<a*>(pb); //error
  • reinterpret_cast<new type>(expression)
a. 它能够进行各种指针之间的转换,无关系的类型也可以,但是不保证安全,慎用
class A { /* ... */ };
class B { /* ... */ };
A * a = new A;
B * b = reinterpret_cast<B*>(a);
b. 可将整形和指针之间进行相互转化(二进制的拷贝),一个很好地用途就是hash
unsigned int Hash( void *p ) {
	unsigned int val = reinterpret_cast<unsigned int>( p );
	return (unsigned int)( val ^ (val >> 31));
}
  • const_cast<new type>(expression)
将const pointer 转换成pointer,但后续操作的安全性不保证。
  const char * c = "sample text";
  char * pc = const_cast<char *> (c) ;
  cout<<pc<<endl;
  pc[1] = '2'; //error, try to modify the string constant.















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值