抑制隐式转换explicit

按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象,如下面所示:

class
String {

String
( const char* p ); // 用C风格的字符串p作为初始化值

//…

}

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

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

class
String {

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

String
( const char* p ); // 用C风格的字符串p作为初始化值

//…

}

下面两种写法比较正常:

String
s2 ( 10 );   //OK 分配10个字节的空字符串

String
s3 = String ( 10 ); //OK 分配10个字节的空字符串

下面两种写法就比较疑惑了:

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

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

s4
和s5 分别把一个int型和char型,隐式转换成了分配若干字节的空字符串,容易令人误解。

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

class
String {

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

String
( const char* p ); // 用C风格的字符串p作为初始化值

//…

}

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

下面两种写法仍然正确:

String
s2 ( 10 );   //OK 分配10个字节的空字符串

String
s3 = String ( 10 ); //OK 分配10个字节的空字符串

下面两种写法就不允许了:

String
s4 = 10; //编译不通过,不允许隐式的转换

String
s5 = ‘a’; //编译不通过,不允许隐式的转换

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

----------------------------------------------------------
explicit
  只对构造函数起作用,用来抑制隐式转换。如:
 
  class   A   {  
          A(int   a);  
  };  
  int   Function(A   a);  
   
  当调用   Function(2)   的时候,2   会隐式转换为   A   类型。这种情况常常不是程序员想要的结果,所以,要避免之,就可以这样写:
 
   
  class   A   {  
          explicit   A(int   a);  
  };  
  int   Function(A   a);  
   
  这样,当调用   Function(2)   的时候,编译器会给出错误信息(除非   Function   有个以   int   为参数的重载形式),这就避免了在程序员毫不知情的情况下出现错误。

总结:explicit
  只对构造函数起作用,用来抑制隐式转换。

时间: 2024-10-07 08:22:05

抑制隐式转换explicit的相关文章

explicit 只对构造函数起作用,用来抑制隐式转换。

class A { private: int a; public: A(int x) :a(x){} void display(){ cout << a << endl; } void display()const{ cout << "ddd" << endl; } }; void f(A a)//因为下面数据是常量,不能用&:因为用const就不能使用display { a.display(); } int main() { A

C++中显式、隐式与explicit关键字

在Qt的开发中看到explicit,由此展开搜索. 隐式:编译器完成的转换,如 int a = 1; float b = 3; float sum; sum = a + b; //a本是int,编译器将a隐式地转化为了float 显式:用户完成的转换,如 float a=1; float b=3; int s; s = (int)a+(int)b;//a与b被显式地转化为了float 对于函数而非数据,这里有另一个例子[引用]: #include <iostream> using namesp

Qt C++中的关键字explicit——防止隐式转换(也就是Java里的装箱),必须写清楚

最近在复习QT,准备做项目了,QT Creator 默认生成的代码 explicit Dialog(QWidget *parent = 0)中,有这么一个关键字explicit,用来修饰构造函数.以前在Windows下写程序的时候,基本上没有碰到这个关键字,那么这个关键字是做什么用的呢? 关键字 explicit 可以禁止“单参数构造函数”被用于自动类型转换,主要用于 "修饰 "构造函数. 指明构造函数只能显示使用,目的是为了防止不必要的隐式转化. 光看这一句似乎不太容易明白,下面,举

C++ explicit关键字避免隐式转换

explicit用来防止由构造函数定义的隐式转换. 要明白它的作用,首先要了解隐式转换:可以用单个实参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换. 例如: class things { public: things(const std::string &name = ""): m_name(name),height(0),weight(10){} int CompareTo(const things & other); std::string m_name

21.C++- ++操作符重载、隐式转换之explicit关键字、类的类型转换函数

++操作符重载 ++操作符分为前置++和后置++,比如: ++a;  a++; ++操作符可以进行全局函数或成员函数重载 重载前置++操作符不需要参数 重载后置++操作符需要一个int类型的占位参数 前置++操作符的返回值为*this 后置++操作符的返回值为临时对象 例如: 转换规则如下所示: 比如: 隐式转换的隐患 隐式转换有时会因为类型不同,得到的结果大有不同,也是常见bug之一. 参考以下示例: 运行打印: 答案并非是-1000. 同样,我们使用构造函数时,也经常使用隐式转换 参考以下示

自定义隐式转换和显式转换c#简单例子

自定义隐式转换和显式转换c#简单例子 (出自朱朱家园http://blog.csdn.net/zhgl7688) 例子:对用户user中,用户名first name和last name进行转换成合成一个限定长度为10个字符新name. 自定义隐式转换: namespace transduction { public partial class transductionForm : Form { public transductionForm() { InitializeComponent();

ORACLE 尽量不使用隐式转换

/*************************************************一.主题:ORACLE 尽量不使用隐式转换 类型转换的两种方式:显示类型转换(Explicit) 自动类型转换(Implicit) *************************************************/ =============================================================================1.1.显示

自己定义隐式转换和显式转换c#简单样例

自己定义隐式转换和显式转换c#简单样例 (出自朱朱家园http://blog.csdn.net/zhgl7688) 样例:对用户user中,usernamefirst name和last name进行转换成合成一个限定长度为10个字符新name. 自己定义隐式转换: namespace transduction { public partial class transductionForm : Form { public transductionForm() { InitializeCompon

【C++自我精讲】基础系列五 隐式转换和显示转换

0 前言 1)C++的类型转换分为两种,一种为隐式转换,另一种为显式转换. 2)C++中应该尽量不要使用转换,尽量使用显式转换来代替隐式转换. 1 隐式转换 定义:隐式转换是系统跟据程序的需要而自动转换的. 1)C++类型(char,int,float,long,double等)的隐式转换: 算术表达式隐式转换顺序为: 1.char - int - long - double 2.float - double //1)算术表达式 int m = 10; double n = m;//n = 10