c++ 中为类重载运算符时成员函数和全局函数的区别
时间: 2023-09-03 17:02:23 浏览: 206
在C++中,重载运算符可以作为成员函数或全局函数来定义。下面是成员函数和全局函数在类重载运算符时的区别。
1. 形式:
成员函数:重载运算符作为类的成员函数被定义,使用类的实例调用。
全局函数:重载运算符作为类外的全局函数被定义,使用运算符符号作为函数名进行调用。
2. 参数:
成员函数:作为成员函数时,重载运算符有一个参数(除了一元运算符,如++, --等)表示运算符的右操作数。左操作数是调用该成员函数的类的实例。
全局函数:作为全局函数时,重载运算符通常有两个参数,分别表示运算符的两个操作数。
3. 实现位置:
成员函数:重载运算符作为类的成员函数实现,因此可以使用类的私有成员变量和保护成员函数。
全局函数:重载运算符作为全局函数时,不能直接访问类的私有成员变量和保护成员函数,需要通过类的公有接口来实现对类的访问。
4. 对称性:
成员函数:由于成员函数将调用者作为左操作数,因此成员函数的操作数的顺序是固定的。例如,对于一个重载的加法运算符,如果a是类的实例,则a.operator+(b)或a+b是可以的,但b.operator+(a)是不行的。
全局函数:全局函数没有这种对称性的问题,因为它不依赖于特定的对象来调用。
综上所述,成员函数和全局函数在类重载运算符时的区别在于形式、参数、实现位置和对称性。选择使用成员函数还是全局函数取决于具体的需求和设计选择。
相关问题
如何在C++中为自定义类型重载算术运算符?
在C++中,为了为自定义类型(如类或结构体)重载算术运算符,你需要在类或结构体中定义这些运算符的成员函数。这里我们以加法操作为例,但同样的原则适用于减法、乘法、除法、取模等其他算术运算符。
首先,确保你有一个类,并且包含一个名为`add`的成员函数,用于执行两个同类型的实例之间的加法:
```cpp
class MyClass {
public:
// 运算符重载示例 - 自定义加法
MyClass operator+(const MyClass& other) const {
MyClass result;
// 实现加法逻辑,例如累加两个对象的属性
result.my_attribute = my_attribute + other.my_attribute;
return result;
}
private:
int my_attribute; // 类型取决于你的具体需求
};
```
如果要覆盖默认的行为(比如加法使用`+`操作符),你需要将相应的成员函数声明为`virtual`(如果它们不是)。对于非成员函数,你可以这样做:
```cpp
MyClass operator+(int left, const MyClass& right) {
return MyClass(left) + right;
}
// 或者
MyClass operator+(const MyClass& left, int right) {
return left + MyClass(right);
}
```
这样,当你对`MyClass`对象调用`+`或`+=`时,会调用上述自定义的`operator+`函数。
小明学习了面向对象程序设计后,以字符指针作为数据成员设计了一个字符串类STRING,请你帮他实现输入输出运算符的重载(>>、<<)。 要求: (1)输入时以输入Enter键作为结束标志,允许输入长度不超过80个字符的可以包含空格、可以为空串的字符序列。 (2)输出时,仅输出字符串中的有效字符。字符串输出结束后,不输出换行符。
好的,这里给出一个实现示例:
```c++
#include <iostream>
#include <cstring>
class STRING {
private:
char* str; // 字符指针作为数据成员
public:
STRING() {
str = new char[81]; // 构造函数中为字符指针分配空间
}
~STRING() {
delete[] str; // 析构函数中释放空间
}
friend std::istream& operator>>(std::istream& is, STRING& s) {
is.getline(s.str, 81); // 以Enter键作为结束标志,最多输入80个字符
return is;
}
friend std::ostream& operator<<(std::ostream& os, const STRING& s) {
os << s.str; // 输出字符串中的有效字符
return os;
}
};
int main() {
STRING s;
std::cin >> s;
std::cout << s;
return 0;
}
```
注意,这里用到了 `getline()` 函数来读取输入的字符串,`getline()` 可以读取包括空格在内的一整行字符串,以回车键作为结束标志。同时,我们还需要在构造函数中为字符指针分配存储空间,在析构函数中释放空间,以避免内存泄漏。最后,输出时需要注意只输出字符串中的有效字符。
阅读全文