1.隐式构造
C++ 中存在隐式构造的现象,即在某些情况下,会隐式调用单参数的构造函数。
1.1 情况一
#include <iostream>
using namespace std;
class Student
{
private:
int age;
public:
Student()
{
age = 0;
cout << "Student() - " << this << endl;
}
Student(int v)
{
age = v;
cout << "Student(int v) - " << this << endl;
}
Student(const Student& stu) // 拷贝构造函数
{
age = stu.age;
cout << "Student(const Student& stu) - " << this << endl;
}
Student& operator=(const Student& stu) // 拷贝赋值运算符
{
age = stu.age;
cout << "Student& operator=(const Student& stu) - " << this << endl;
return *this;
}
~Student()
{
cout << "~Student() - " << this << endl;
}
void display()
{
cout << "display() - " << this << endl;
}
};
int main()
{
Student stu1 = 20;
return 0;
}
1.2 情况二
#include <iostream>
using namespace std;
class Student
{
private:
int age;
public:
Student()
{
age = 0;
cout << "Student() - " << this << endl;
}
Student(int v)
{
age = v;
cout << "Student(int v) - " << this << endl;
}
Student(const Student& stu) // 拷贝构造函数
{
age = stu.age;
cout << "Student(const Student& stu) - " << this << endl;
}
Student& operator=(const Student& stu) // 拷贝赋值运算符
{
age = stu.age;
cout << "Student& operator=(const Student& stu) - " << this << endl;
return *this;
}
~Student()
{
cout << "~Student() - " << this << endl;
}
void display()
{
cout << "display() - " << this << endl;
}
};
void test1(Student stu)
{
}
int main()
{
test1(30);
return 0;
}
1.3 情况三
#include <iostream>
using namespace std;
class Student
{
private:
int age;
public:
Student()
{
age = 0;
cout << "Student() - " << this << endl;
}
Student(int v)
{
age = v;
cout << "Student(int v) - " << this << endl;
}
Student(const Student& stu) // 拷贝构造函数
{
age = stu.age;
cout << "Student(const Student& stu) - " << this << endl;
}
Student& operator=(const Student& stu) // 拷贝赋值运算符
{
age = stu.age;
cout << "Student& operator=(const Student& stu) - " << this << endl;
return *this;
}
~Student()
{
cout << "~Student() - " << this << endl;
}
void display()
{
cout << "display() - " << this << endl;
}
};
Student test2()
{
return 40;
}
int main()
{
test2();
return 0;
}
2.explicit
上面的三个代码都隐式调用了单参数的构造函数,将一个整数类型 int
转换为类类型 Student
。但是,这种隐式类型转换有些不伦不类,容易让人产生疑惑,有什么办法可以阻止这种用法呢?
答案:使用 explicit
关键字。explicit
指定构造函数或转换函数为显式,即不能用于隐式转换和复制初始化。
#include <iostream>
using namespace std;
class Student
{
private:
int age;
public:
Student()
{
age = 0;
cout << "Student() - " << this << endl;
}
explicit Student(int a)
{
age = a;
cout << "Student(int v) - " << this << endl;
}
Student(const Student& stu) // 拷贝构造函数
{
age = stu.age;
cout << "Student(const Student& stu) - " << this << endl;
}
Student& operator=(const Student& stu) // 拷贝赋值运算符
{
age = stu.age;
cout << "Student& operator=(const Student& stu) - " << this << endl;
return *this;
}
~Student()
{
cout << "~Student() - " << this << endl;
}
void display()
{
cout << "display() - " << this << endl;
}
};
int main()
{
Student stu1 = 18; // 报错
Student stu2 = { 20 }; // 报错
return 0;
}
explicit
关键字只对带一个参数的类构造函数有效,如果类构造函数参数大于或等于两个,是不会产生隐式转换的,所以 explicit
关键字也就无效了。
但是,如果类构造函数除了第一个参数以外的其他参数都有默认值,此时等效于只有一个参数的类构造函数,那么 explicit
关键字依然有效。
#include <iostream>
using namespace std;
class Student
{
private:
int age;
int height;
public:
Student()
{
age = 0;
height = 0;
cout << "Student() - " << this << endl;
}
explicit Student(int a, int b = 180)
{
age = a;
height = b;
cout << "Student(int v) - " << this << endl;
}
Student(const Student& stu) // 拷贝构造函数
{
age = stu.age;
height = stu.height;
cout << "Student(const Student& stu) - " << this << endl;
}
Student& operator=(const Student& stu) // 拷贝赋值运算符
{
age = stu.age;
height = stu.height;
cout << "Student& operator=(const Student& stu) - " << this << endl;
return *this;
}
~Student()
{
cout << "~Student() - " << this << endl;
}
void display()
{
cout << "display() - " << this << endl;
}
};
int main()
{
Student stu1 = 18; // 报错
Student stu2 = { 20 }; // 报错
return 0;
}