目录
类类型转换(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
-
解释
抑制构造函数定义的隐式转换
-
语法
- 在类内声明构造函数时使用,在类外部定义时不应重复。
- 只对一个实参的构造函数有效。因为需要多个实参的构造函数不能用于执行隐式转换,所以在这种场景不需要explicit. 虽然不需要但是加了也不会报错。
- explicit只能用于直接初始化
- 可以为转换显式的使用构造函数
- 代码示例
#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;
}