您的位置:首页 > 编程语言 > C语言/C++

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

2014-02-26 22:30 375 查看
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;

  }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: