一个例子了解operator+
创始人
2024-05-30 13:02:14
0

先来看一个题目:

#include 
using namespace std;class A {int a;
public:A(int x=0): a(x){}void f(){cout << a;}A operator+(int op) {A T;T.a = a + op;return T;}
};int main()
{A a1, a2(2);cout << a1 + a2;  // A(a1 + a2).f();	 // B(a1 + 3).f();	 // C(3 + a1).f();	 // Dreturn 0;
}

以上 main 函数中 A,B,C,D 四个选项能通过编译?

考验对 C++ 中运算符重载的理解的时候到了!先给出答案:

cout << a1 + a2;	// A  --> failed
(a1 + a2).f();		// B  --> failed
(a1 + 3).f();		// C  --> passed
(3 + a1).f();		// D  --> passed

为啥会是这样呢?看一个稍复杂些的例子(把各种情况都列一下):

#include 
using namespace std;class A {int a;
public:A(int x=0): a(x){}void f(){cout << "operator+(int): " << a << endl;}A operator+(A op) {A T;T.a = a + op.a;return T;}
};class B {int b;
public:B(int x=0): b(x) {}void f() {cout << "operator+(Obj): " << b << endl;}B operator+(int op) {B T;T.b = b + op;return T;}
};int main()
{A a1, a2(2);B b1, b2(2);// operator+ 的参数为 A 时,int 型 op 作为第二操作数(a1 + 3).f(); // pass// operator+ 的参数为 A 时,int 型 op 作为第一操作数(3 + a1).f();  // failed// operator+ 的参数为 A 时,A 型 op 作为操作数(a1 + a2).f();  // pass// operator+ 的参数为 int 时,int 型 op 作为第二操作数(b1 + 3).f();  // pass// operator+ 的参数为 int 时,int 型 op 作为第一操作数(3 + b1).f();  // failed// operator+ 的参数为 int 时,B 型 op 作为操作数(b1 + b2).f(); // failedreturn 0;
}

以上各个例子,可以发现一个规律:加法操作操作符有两个操作数,能否能够编译取决于对象是第几个操作数以及重载 operator+ 时的参数类型,且成员函数默认把 this 指针当作第一个参数传进去了。例如,(a1 + 3).f()pass 是因为定义了 operator+(A),等价于 operator+(A, A),因为 3 可以通过构造函数转化为 A(3) 所以执行时相当于:第一个操作数是 a1,所以调用的是 A 重载的加法运算符,然后用 3 实例化为一个 A 类型的对象,再传给 operator+。所以,能否编译通过,我们要看第一个操作数的类型来确定,再根据第二个操作数来确定参数的类型,如果第一个操作数的类型中定义了该签名的 operator+ 则可以编译通过,否则 failed。所以:

 // operator+ 的参数为 A 时,int 型 op 作为第二操作数(a1 + 3).f(); // pass。目标:operator+(A, int),存在:operator(A*, A),3 可以实例化为 A,所以 passed// operator+ 的参数为 A 时,int 型 op 作为第一操作数(3 + a1).f();  // failed。目标:operator+(int, A),存在:operator(A*, A),不匹配,如果 A 中引入友元函数 operator(int, A) 则可以 passed// operator+ 的参数为 A 时,A 型 op 作为操作数(a1 + a2).f();  // pass。显然!// operator+ 的参数为 int 时,int 型 op 作为第二操作数(b1 + 3).f();  // pass。目标:operator+(B, int),存在:operator+(B*, int)// operator+ 的参数为 int 时,int 型 op 作为第一操作数(3 + b1).f();  // failed。目标:operator+(int, B),存在:operator+(B*, int),不匹配,如果 B 中引入友元函数 operator+(int, B) 则 passed// operator+ 的参数为 int 时,B 型 op 作为操作数(b1 + b2).f(); // failed。目标:operator+(B, B),存在:operator+(B*, int),不匹配

引入友元函数的例子:

class A {int a;
public:A(int x=0): a(x){}void f(){cout << "operator+(int): " << a << endl;}A operator+(A op) {  // 其实等价于:operator+(A* , A),this 指针作为第一个参数A T;T.a = a + op.a;return T;}friend A operator+(int op1, A op2) {  // 友元函数A T;T.a = op1 + op2.a;return T;}
};

这种情况下 (3 + a1).f() 即可 passed

结论:根据操作数的类型和位置确定需要的 operator+ 的具体函数签名,如果在名字空间中能找到定义的函数则可以,否则 failed!

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...