关键字explicit&&c++四种类型转换相关关键字

1.      关键字explicit

  通过关键字explicit的作用,我们可以禁止“单参数构造函数”被用于自动类别转换。

  在 C++ 中, 如果一个类有只有一个参数的构造函数,C++ 允许一种特殊的声明类变量的方式。在这种情况下,可以直接将一个对应于构造函数参数类型的数据直接赋值给类变量,编译器在编译时会自动进行类型转换,将对应于构造函数参数类型的数据转换为类的对象。如果在构造函数前加上 explicit 修饰词, 则会禁止这种自动转换,在这种情况下,即使将对应于构造函数参数类型的数据直接赋值给类变量,编译器也会报错。

  例如:

  class String

  {

  String(cost char * p);

  };

  String s1= “hello”;  //ok 隐式转换,等价于String s1=String(“hello”);

  但是有的时候可能不需要这种隐式转换:

  class String

  {

  String(int  n);   //本意是预先分配n个字节给字符串

  String(constchar * p);

  };

  下面正常写法:

  String s2(10);

  String s3=String(10);

  //都分配10个字节的空字符串

  但下面的写法就有问题了:

  String s4=10;  //编译通过,也分配10个字节的空字符串

  String s5= ‘a’;  //编译通过,分配int(‘a’)个字节的空字符串

  s4和s5 分别把一个int类型和char类型,隐式转换成了分配若干字节的字符串。

  为了避免这种错误的发生,我们要显示的转换,使用explicit关键字:

  class String

  {

  public:

  explicit  String(int n);

  String(const char * p);

  };

  加上explicit,就抑制String(int n)的隐式转换

  这样就不允许:

  String s4=10;

  String s5= ‘a’;

  因此,某些时候,explicit可以有效得防止构造函数的隐式转换带来的错误或误解。


2.      C++中的四种类型转换操作符

  2.1.static_cast

  类似于C风格的强制转换。

  1.基类和子类之间转换:其中子类指针转换成父类指针是安全的;但父类指针转换成子类指针是不安全的。(基类和子类之间的动态类型转换建议用dynamic_cast)
       2. 基本数据类型转换。enum, struct, int, char, float等。static_cast不能进行无关类型(如非基类和子类)指针之间的转换。
       3. 把空指针转换成目标类型的空指针。
       4. 把任何类型的表达式转换成void类型。
       5. static_cast不能去掉类型的const、volitale属性(用const_cast)。

  例如:

  float  x;

  ….

  cout<<static_cast<int>(x);

  2.2.dynamic_cast

  将多态型别向下转型:

  将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理, 

  即会作一定的判断。 
       对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针; 
       对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用。 

  注意:dynamic_cast在将父类cast到子类时,父类必须要有虚函数。

  例如:

  class  Car;

  class  Cabriolet: public Car

  {

  };

  class Limousine : public Car

  {

  };

  void f(Car *cp)

  {

  Cabriolet *p=dynamic_cast<Cabriolet *>(cp);

  if(p==NULL)

  {

  //转换失败

  }

  }

  2.3const_cast

  去掉类型的const或volatile属性。

  2.4.reinterpret_cast

  reinterpret_cast 任意两种指针类型之间,指针和数值类型直接的转换,最危险的一种转换

  综合例子:

  #include<iostream>

  using namespace std;

  #include<cstdlib>

  int main()

  {

  intn=static_cast<int>(45.67); //double类型的数45.67转换为int类型的,相当于

  //int n=(int)45.67

  int *p=static_cast<int*>(calloc(sizeof(int),10))//相当于强制转换的

  //int *p=(int *)........

  const int k=n;

  cout<<"k="<<k<<endl;

  const_cast<int&>(k)=789;  //const_cast 临时去掉const类型 这是k可以修改

  //转换为一个int的引用类型的k 为左值可以赋值给他修改他

  cout<<"k="<<k<<endl;       //输出结果为: k=789

  float f=123.45;

  p=reinterpret_cast<int*>(&f); 

  cout<<*p<<endl;           //

  n=int(12.34);              //一种转换的方法  double转化为int类型

  n=int();                   //输出的n的结果为0

  //变量的初始化:

  int m(100);                //变量的一种初始化的方法

  cout<<"m="<<m<<endl;

  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值