0、People是一个类;
People p1(1, 2); //调用构造函数
People p2(2, 4); //调用构造函数
1、 People p = 4; //会调用构造函数,假设构造函数的原型是:People(int a, int b = 1);
#include <iostream>
using namespace std;
class People{
public:
People(int a, int b = 1){
num = double(a)/b;
cout << "构造函数" << endl;
}
private:
double num;
};
int main()
{
People p1(1, 2);
People p2(2, 4);
People p = 4; //会调用构造函数,假设构造函数的原型是:People(int a, int b = 1);
return 0;
}
注意People p = 4;此时相当于:People p(4);调用构造函数
之所以强调这一点是因为:People p = p1此时相当于People p(p1);调用复制构造函数;
2、 People p = p1 + 4; //会调用重载的加号运算符:People operator + (double number);再因为返回的是临时对象而调用构造函数
#include <iostream>
using namespace std;
class People{
public:
People(int a, int b = 1){
num = double(a)/b;
cout << "构造函数" << endl;
}
People operator + (double number){
cout << "operator + (double number) " << endl;
return People(num + number, 1);//调用构造函数;
}
private:
double num;
};
int main()
{
People p1(1, 2);
People p2(2, 4);
People p = p1 + 4;//会调用重载的加号运算符:People operator + (double number);然后调用构造函数
return 0;
}
3、People p = p1 + 4; //会先调用operator double() { return double(num); },再调用构造函数;
#include <iostream>
using namespace std;
class People{
public:
People(int a, int b = 1){
num = double(a)/b;
cout << "构造函数" << endl;
}
People operator + (People & people){//形参如果不使用引用就会调用一次构造函数;
cout << "重载的+运算符" << endl;
return People(num + people.num, 1);//调用一次构造函数
}
People operator = (double number){
cout << "重载的operator = (double number) " << endl;
return People(num + number, 1);//调用构造函数;
}
operator double(){
cout << "调用operator double()" << endl;
return num;
}
private:
double num;
};
int main()
{
People p1(1, 2);
People p2(2, 4);
People p = p1 + 4;//会先调用operator double() { return double(num); };再调用构造函数;
return 0;
}
这个的原理是:先将p1转化为double,即调用 operator double();在进行double的加法操作,计算出结果以后即变成了和例1类似的过程,即再调用一次构造函数;
关于这一点和侯捷老师讲的视频有点儿出入,按照侯捷老师的说法,这个例子应该会报ambiguous的错误,
因为People p = p1 + 4;这一句可以将p1转化为4(调用 operator double()),然后double相加;
也可以将4转化为People类型(此处调用构造函数,此处存在疑问。。。。因为一个单独的4会主动的变为People吗?),然后两个People相加(此处调用People operator + (People & people));
更正::---------------------------------------------------------------
红线处侯捷老师讲的是正确的,因为我的第3个例子People operator + (People & people)形参带引用,所以才没有出现ambiguous的错误,如果不带&的话,就会出现“error: ambiguous overload for ‘operator+’ (operand types are ‘People’ and ‘int’)|”的错误.此时将构造函数前面加上explicit关键字还会报错,因为加上explicit关键字以后,整数4便不会往People类进行转化了,或许你会想那可以将p1转化为整数double啊,然后double + int = double,注意到这一步还是可以的,但是,再往下就没办法走了,因为构造函数是explicit的,People p = (double)x 约等于 People p(x),explicit关键字禁止进行复制(拷贝)构造,详细见C++ primer,P265.
4、People p = p1 + 4;
#include <iostream>
using namespace std;
class People{
public:
People(int a, int b = 1){
num = double(a)/b;
cout << "构造函数" << endl;
}
People operator + (People people){//调用一次构造函数;
cout << "重载的+运算符" << endl;
return People(num + people.num, 1);//调用一次构造函数
}
private:
double num;
};
int main()
{
People p1(1, 2);
People p2(2, 4);
People p = p1 + 4;
return 0;
}
整个执行过程:先调用构造函数将整数4转化为People类型进行参数的传递,然后调用重载的People operator + (People people)(此时更好理解的一种方式是:函数去调用重载的People operator + (People people),由于其形参是People类型,所以才将整数4强制转化了为了People(4)类型,见深入理解 运算符的重载),然后重载加号运算符的重载函数在返回的时候会调用构造函数构造一个临时对象。
即:构造函数 → 重载的+运算符 → 构造函数
总结:
1、 People p = 4; //会调用构造函数,假设构造函数的原型是:People(int a, int b = 1);
2、 People p = p1 + 4; //会调用重载的加号运算符:People operator + (double number);再因为返回的是临时对象而调用构造函数
3、 People p = p1 + 4; //会先调用operator double() { return double(num); },再调用构造函数;
4、 People p = p1 + 4; //构造函数 → 重载的+运算符 → 构造函数