C++关于运算符重载

友元函数不是类成员函数,而是一个普通函数。友元函数只是在类中用friend修饰的函数,之所以在类中声明,是为了使这个普通函数可以访问类中的私有成员。

在运算符重载中,如果运算符重载函数被定义为类成员函数,则可以省略一个函数参数,因为已经隐含了this指针;如果运算符重载函数不是类成员函数,当然也就没有this指针了,但由于运算过程中要访问类的私有数据成员,所以需要将运算符重载函数在类中声明为友元函数。当然,如果类中的数据成员是public的,则无须将运算符重载函数在类中声明为友元函数。

对于双目运算,一般运算符左边的操作数就是运算符重载函数的调用者。
对于成员函数,函数的调用者就是运算符左边的操作数,而cout对象是ostream类的对象,所以,<<运算符重载函数只能作为友元函数(因为调用<<运算符重载函数的对象是cout,而不是自定义数据类型的对象,否则就会改变<<运算符的传统使用风格),如果类的数据成员是public的,则<<运算符重载函数可以不声明为类的友元。

总之,当运算符重载函数作为类成员函数时,this所指的对象必须作为运算符的一个操作数。重载的运算符必须和用户自定义的类型的对象一起使用,其参数应该至少有一个是类对象,像
int operator+(int a,int b){return a-b;}
就是错误的做法。

双目运算符重载函数的形参个数如果是两个,则只能作为全局函数,不能作为类成员函数。

### C++ 运算符重载的使用方法 C++ 中的运算符重载是一种允许为已有的运算符赋予新的含义的技术。它主要用于型的对象之间执行操作,使代码更具可读性和直观性。 #### 成员函数实现运算符重载 运算符重载可以通过的成员函数或友元函数来实现。以下是一个通过成员函数实现加法运算符 (`+`) 的示例: ```cpp #include <iostream> using namespace std; class A { private: int x, y; public: A(int x1 = 0, int y1 = 0) { x = x1; y = y1; } // 重载 + 运算符 A operator+(const A& a) const { return A(x + a.x, y + a.y); // 返回一个临对象作为结果 } void show() { cout << "x=" << x << ", y=" << y << endl; } }; int main() { A a1(1, 2); A a2(3, 4); A a = a1 + a2; // 使用重载的 + 运算符 a.show(); // 输出: x=4, y=6 return 0; } ``` 在上述代码中,`operator+` 是一个成员函数,它接受一个 `const A&` 型的参数,并返回一个新的 `A` 对象。这个函数用于实现两个 `A` 对象的加法操作 [^1]。 #### 友元函数实现运算符重载 另一种方式是使用友元函数进行运算符重载。这种方式更适合需要访问私有成员的操作符(如流输出运算符 `<<`)。以下是一个示例: ```cpp #include <iostream> using namespace std; class A { private: int x, y; public: A(int x1 = 0, int y1 = 0) { x = x1; y = y1; } // 声明友元函数 friend A operator+(const A& a1, const A& a2); void show() { cout << "x=" << x << ", y=" << y << endl; } }; // 友元函数实现 + 运算符重载 A operator+(const A& a1, const A& a2) { return A(a1.x + a2.x, a1.y + a2.y); } int main() { A a1(1, 2); A a2(3, 4); A a = a1 + a2; // 使用友元函数重载的 + 运算符 a.show(); // 输出: x=4, y=6 return 0; } ``` 在这个例子中,`operator+` 被声明为 `A` 的友元函数,并在外部实现了该函数 [^1]。 --- ### C++ 运算符重载的实现原理 运算符重载本质上是通过函数调用机制来实现的。当程序中使用了重载运算符,编译器会根据运算符型和操作数的型选择合适的函数进行调用。 #### 参数匹配与函数解析 C++ 编译器会根据操作数的型和数量来决定调用哪个重载函数。例如,在 `a1 + a2` 中,如果 `a1` 和 `a2` 都是 `A` 的对象,则编译器会选择 `A::operator+` 或者相应的友元函数 [^1]。 #### 返回值与临对象 在重载运算符,通常会返回一个新的对象作为结果。例如,在 `A(x + a.x, y + a.y)` 中,构造了一个临对象并将其作为返回值。这种设计确保了运算符的链式调用(如 `a1 + a2 + a3`)能够正常工作 [^1]。 #### 限制与注意事项 - **不可重载运算符**:某些运算符不能被重载,例如作用域解析运算符 `::`、条件运算符 `?:` 等。 - **保持语义一致性**:重载运算符应尽量保持其原有的语义,避免造成混淆。 - **效率问题**:频繁创建临对象可能会影响性能,因此可以考虑使用引用或优化构造函数来减少开销 。 --- ### 示例:重载 `<<` 运算符以支持流输出 为了方便调试和输出信息,可以重载 `<<` 运算符以支持将自定义的对象直接输出到流中: ```cpp #include <iostream> using namespace std; class A { private: int x, y; public: A(int x1 = 0, int y1 = 0) { x = x1; y = y1; } // 声明友元函数 friend ostream& operator<<(ostream& os, const A& a); }; // 重载 << 运算符 ostream& operator<<(ostream& os, const A& a) { os << "x=" << a.x << ", y=" << a.y; return os; } int main() { A a(5, 6); cout << a << endl; // 输出: x=5, y=6 return 0; } ``` 在这个例子中,`operator<<` 被重载为一个友元函数,使得 `cout << a` 可以直接输出对象的信息 [^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值