_RightHand

导航

 

类类型转换(class-type conversions)

类类型转换转换构造函数类型转换运算符共同定义,又称为用户定义的类型转换(user-defined conversions)

隐式转换与转换构造函数(converting constructor)

能通过一个参数调用的构造函数,它定义了一条从构造函数的参数类型向类类型隐式转换的规则,这种构造函数叫做转换构造函数

  • 代码示例
#include <iostream>
using namespace std;

class A {
public:
    A(int a) : a_(a) {}
    void Debug() {
    	cout << "a_=" << a_ << endl;
    }
private:
    int a_;
};

int main() 
{
    A a = 7;// 此处发生了隐式转换,7被转换为了A类型.
    a.Debug(); // 运行显示a_=7
    return 0;
}

直接初始化(direct initialization)和拷贝初始化(copy initialization)

下面这种方式是直接初始化:

string s2("world");
string s3(3, 'a'); // s3的内容是aaa

使用等号初始化一个变量时执行的是拷贝初始化:

string s1 = "hello";

当只有一个参数时,两种初始化方式使用起来都比较方便。

当有多个参数时,如果使用拷贝初始化有一些需要注意的地方,使用示例解释:

string s4 = string(3, 'c');

实际上这条语句相当于下面的两条语句

string tmp(3, 'c');
string s4 = tmp;

即先创建了一个临时对象,然后进行了拷贝操作。

explicit

  • 解释

    抑制构造函数定义的隐式转换

  • 语法

  1. 在类内声明构造函数时使用,在类外部定义时不应重复。
  2. 只对一个实参的构造函数有效。因为需要多个实参的构造函数不能用于执行隐式转换,所以在这种场景不需要explicit. 虽然不需要但是加了也不会报错。
  3. explicit只能用于直接初始化
  4. 可以为转换显式的使用构造函数
  • 代码示例
#include <iostream>
using namespace std;

class A {
public:
    A() : a_(0) {}
    explicit A(int a) : a_(a) {}
    void Debug() {
    	cout << "a_=" << a_ << endl;
    }
private:
    int a_;
};

class B {
public:
    B() : v1_(0), v2_(0) {}
    // 下面不需要写explicit,但是写了也不会出错
    explicit B(int v1, int v2) : v1_(v1), v2_(v2) {} 
    void Debug() {
        cout << "v1_=" << v1_ << endl;
        cout << "v2_=" << v2_ << endl;
    }
private:
    int v1_;
    int v2_;
};

class C {
public:
    // 这个构造函数相当于三个构造函数,有一个参数的,有两个参数的,没有参数的。
    C(int v1 = 0, int v2 = 0) : v1_(v1), v2_(v2) {}
    void Debug() {
        cout << "v1_=" << v1_ << endl;
        cout << "v2_=" << v2_ << endl;
    }
private:
    int v1_;
    int v2_;
}

class D {
public:
    // 这个构造函数相当于三个构造函数,有一个参数的,有两个参数的,没有参数的。
    explicit D(int v1 = 0, int v2 = 0) : v1_(v1), v2_(v2) {}
    void Debug() {
        cout << "v1_=" << v1_ << endl;
        cout << "v2_=" << v2_ << endl;
    }
private:
    int v1_;
    int v2_;
}

int main() 
{
    A a;
    // a = 7; // 编译出错
    
    B b(1,2);
    b.Debug(); // 运行显示:v1_=1 v2_=2
    
    C c = 8;
    c.Debug(); //运行显示:v1_=7	v2_=0
    
    // D d = 8; // 编译出错
    D d(D(8)); // 为转换显式的使用构造函数, 先创建一个临时对象
    D.Debug;
    
    return 0;
}
posted on 2020-11-05 10:01  _RightHand  阅读(514)  评论(0编辑  收藏  举报