<转> 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   只对构造函数起作用,用来抑制隐式转换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个完整的 C++ 程序,满足您的要求: ```cpp #include <iostream> using namespace std; class Complex { private: double real; // 实部 double imag; // 虚部 public: Complex() { // 默认构造函数 real = 0; imag = 0; } Complex(double r, double i) { // 带参数构造函数 real = r; imag = i; } Complex(const Complex& c) { // 拷贝构造函数 real = c.real; imag = c.imag; } ~Complex() { // 析构函数 // do nothing } void setReal(double r) { // 设置实部 real = r; } void setImag(double i) { // 设置虚部 imag = i; } double getReal() const { // 获取实部 return real; } double getImag() const { // 获取虚部 return imag; } Complex operator+(const Complex& c) const { // 运算符重载 + return Complex(real + c.real, imag + c.imag); } Complex operator-(const Complex& c) const { // 运算符重载 - return Complex(real - c.real, imag - c.imag); } Complex operator*(const Complex& c) const { // 运算符重载 * return Complex(real * c.real - imag * c.imag, real * c.imag + imag * c.real); } Complex operator/(const Complex& c) const { // 运算符重载 / double denominator = c.real * c.real + c.imag * c.imag; return Complex((real * c.real + imag * c.imag) / denominator, (imag * c.real - real * c.imag) / denominator); } Complex operator++() { // 运算符重载前置 ++ real++; imag++; return *this; } Complex operator++(int) { // 运算符重载后置 ++ Complex tmp(*this); real++; imag++; return tmp; } Complex operator--() { // 运算符重载前置 -- real--; imag--; return *this; } Complex operator--(int) { // 运算符重载后置 -- Complex tmp(*this); real--; imag--; return tmp; } friend istream& operator>>(istream& is, Complex& c) { // 运算符重载 >> is >> c.real >> c.imag; return is; } friend ostream& operator<<(ostream& os, const Complex& c) { // 运算符重载 << os << c.real << " + " << c.imag << "i"; return os; } explicit operator double() const { // 类型换函数 return real; } }; int main() { Complex c1(1.0, 2.0); Complex c2(3.0, 4.0); // 运算符重载 Complex c3 = c1 + c2; Complex c4 = c1 - c2; Complex c5 = c1 * c2; Complex c6 = c1 / c2; Complex c7 = ++c1; Complex c8 = c2++; Complex c9 = --c1; Complex c10 = c2--; cout << "c1 = " << c1 << endl; cout << "c2 = " << c2 << endl; cout << "c1 + c2 = " << c3 << endl; cout << "c1 - c2 = " << c4 << endl; cout << "c1 * c2 = " << c5 << endl; cout << "c1 / c2 = " << c6 << endl; cout << "++c1 = " << c7 << endl; cout << "c2++ = " << c8 << endl; cout << "--c1 = " << c9 << endl; cout << "c2-- = " << c10 << endl; // 类型换 double d = (double)c1; cout << "double(c1) = " << d << endl; return 0; } ``` 程序中定义了一个 `Complex` 类,实现了复数的加、减、乘、除、前置/后置自增/自减、输入输出运算符重载以及类型换。在 `main` 函数中进行了测试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值