c\c++复习基础要点09---关键字explicit c++四种类型转换

来源:互联网 发布:egd网络小黄金 编辑:程序博客网 时间:2024/05/16 23:40

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.3.const_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;

 

}

原创粉丝点击