目录
运算符重载概念:
对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的类型数据
+运算符重载
1.成员函数重载+号
#include<iostream>
using namespace std;
class person
{
public:
// 1. 成员函数重载加号运算符
// 这里重载了加号运算符,使得两个person对象相加时,可直接通过加号进行操作
person operator+(person& p)
{
person temp;
temp.m_a = this->m_a + p.m_a; // 对m_a进行相加操作
temp.m_b = this->m_b + p.m_b; // 对m_b进行相加操作
return temp; // 返回相加后的结果
}
int m_a;
int m_b;
};
void test01()
{
person p1;
p1.m_a = 10;
p1.m_b = 20;
person p2;
p2.m_a = 10;
p2.m_b = 20;
person p3 = p1 + p2; // 将p1和p2相加的结果赋值给p3
cout << p3.m_a << endl; // 输出p3的m_a值
cout << p3.m_b << endl; // 输出p3的m_b值
}
int main()
{
test01(); // 调用test01函数进行测试
system("pause"); // 暂停系统, Windows下使用
return 0;
}
以上代码定义了一个person
类,并重载了+
运算符,使得两个person
对象可以通过+
进行相加操作。测试时创建了两个person
对象p1
和p2
,将它们相加的结果赋值给p3
,然后输出p3
的成员变量m_a
和m_b
的值。
2.全局函数重载+号
#include <iostream>
using namespace std;
class MyNumber
{
private:
int value;
public:
MyNumber(int val) : value(val) {}
int getValue() const { return value; }
// 友元函数,全局函数重载加号运算符
friend MyNumber operator+(const MyNumber& num1, const MyNumber& num2);
};
// 全局函数重载加号运算符
MyNumber operator+(const MyNumber& num1, const MyNumber& num2)
{
int sum = num1.value + num2.value;
return MyNumber(sum);
}
int main()
{
MyNumber num1(5);
MyNumber num2(7);
MyNumber sum = num1 + num2; // 使用重载的加号运算符进行相加操作
cout << "num1 = " << num1.getValue() << endl;
cout << "num2 = " << num2.getValue() << endl;
cout << "sum = " << sum.getValue() << endl;
return 0;
}
打印结果:
在上述示例代码中,定义了一个名为MyNumber
的类,其中包含一个私有成员变量value
和构造函数。
为了使全局函数能够访问MyNumber
类的私有成员,我们将该全局函数声明为MyNumber
类的友元函数。在这个友元函数operator+
中,我们重载了加号运算符,实现了两个MyNumber
对象相加操作,并返回一个新的MyNumber
对象作为结果。
在main
函数中,我们创建了两个MyNumber
对象num1
和num2
,然后使用重载的加号运算符将它们相加,将结果赋值给sum
。最后,通过getValue
成员函数分别输出num1
、num2
和sum
的值。
总结:对于内置的数据类型的表达式的运算符是不可能改变的
<<运算符重载
#include <iostream>
using namespace std;
class Point
{
private:
int x, y;
public:
Point(int a = 0, int b = 0) : x(a), y(b) {}
int getX() const { return x; }
int getY() const { return y; }
// 友元函数,全局函数重载输出运算符
friend ostream& operator<<(ostream& os, const Point& p);
};
// 全局函数重载输出运算符
ostream& operator<<(ostream& os, const Point& p)
{
os << "(" << p.x << ", " << p.y << ")";
return os;
}
int main()
{
Point p(3, 5);
cout << "The coordinates of p: " << p << endl;
return 0;
}
输出结果为:
The coordinates of p: (3, 5)
在上述示例代码中,定义了一个名为Point
的类,其中包含了两个私有成员变量x
和y
,以及构造函数和获取成员变量的成员函数。
为了实现以自定义的方式输出Point
类对象,我们重载了输出运算符<<
。全局函数operator<<
接受一个ostream
对象os
和一个Point
对象p
作为参数。在函数体中,我们使用os
对象来输出p
的坐标信息。
在main
函数中,我们创建了一个Point
对象p
,然后使用重载的输出运算符将p
输出到标准输出流中。输出的结果将会是形如(3, 5)
的坐标信息。
递增运算符重载
简单例子
#include <iostream>
using namespace std;
class MyNumber
{
private:
int value;
public:
MyNumber(int val) : value(val) {}
int getValue() const
{
return value;
}
// 重载前置递增运算符
MyNumber& operator++()
{
value++;
return *this;
}
// 重载后置递增运算符
MyNumber operator++(int)
{
MyNumber temp(value);
value++;
return temp;
}
};
int main()
{
MyNumber num(5);
cout << "原始值:" << num.getValue() << endl;
MyNumber preIncrement = ++num; // 前置递增运算符
cout << "前置递增后的值:" << num.getValue() << endl;
cout << "前置递增值:" << preIncrement.getValue() << endl;
MyNumber postIncrement = num++; // 后置递增运算符
cout << "后置递增后的值:" << num.getValue() << endl;
cout << "后置递增值:" << postIncrement.getValue() << endl;
return 0;
}
在上述示例代码中,定义了一个名为MyNumber
的类,其中包含一个私有成员变量value
和构造函数。
在MyNumber
类中,我们重载了前置递增运算符(++num
)和后置递增运算符(num++
)。前置递增运算符函数返回一个引用,先将value
成员变量加1,然后返回递增后的对象。后置递增运算符函数接受一个额外的整型参数(通常为0),用于区分前置和后置递增运算符,创建一个临时对象保存递增前的值,然后将value
成员变量加1,并返回临时对象。
注意:区别前置加加和后置加加的返回类型,看是否错误的进行了重载函数。
在main
函数中,我们创建了一个MyNumber
对象num
,然后进行前置递增运算和后置递增运算。我们将递增后的num
对象的值以及返回的递增前的对象的值进行输出。
输出结果为:
原始值:5
前置递增后的值:6
前置递增值:6
后置递增后的值:7
后置递增值:6
总结:前置++返回引用,后置++返回值, 还要加参数,区别重置函数。
赋值运算符重载
如何重载
#include <iostream>
using namespace std;
class MyClass
{
private:
int value;
public:
MyClass(int val) : value(val) {}
int getValue() const
{
return value;
}
// 赋值运算符重载
MyClass& operator=(const MyClass& other)
{
if (this != &other) { // 检查自我赋值
value = other.value;
}
return *this;
}
};
int main()
{
MyClass obj1(5);
MyClass obj2(10);
cout << "obj1的初始值: " << obj1.getValue() << endl;
cout << "obj2的初始值: " << obj2.getValue() << endl;
obj1 = obj2; // 使用赋值运算符将obj2的值赋给obj1
cout << "赋值后,obj1的值: " << obj1.getValue() << endl;
return 0;
}
在上述示例代码中,我们在MyClass
类中重载了赋值运算符(operator=
)。该函数接收一个常量引用参数 other
,表示赋值运算符右侧的对象。
在重载函数中,我们首先进行自我赋值检查,以避免在赋值时发生错误。然后,将other
对象的值赋给this
指针所指向的对象的value
成员变量。
在main
函数中,我们创建了两个MyClass
对象 obj1
和 obj2
。然后使用赋值运算符将 obj2
的值赋给了 obj1
。最后输出 obj1
的值进行验证。
输出结果为:
obj1的初始值: 5
obj2的初始值: 10
赋值后,obj1的值: 10
什么时候重载
当类中含有指针成员变量时,需要深拷贝对象的内容而不只是复制指针的地址。通过重载赋值运算符,可以在对象赋值时自定义深拷贝的行为,确保指针所指的资源得到正确的复制和释放。
当类中存在动态分配的资源,如文件句柄、网络连接等,需要在对象赋值时确保资源的正确释放和转移。
当类中含有其他类对象作为成员变量时,通过重载赋值运算符,可以实现对成员对象的赋值操作。
当使用类的对象进行赋值操作时,希望自定义赋值的行为,例如执行额外的检查、记录操作日志等。
关系运算符重载
简单例子:
#include <iostream>
using namespace std;
class Student
{
private:
int age;
public:
Student(int studentAge) : age(studentAge) {}
// 重载等于运算符
bool operator==(const Student& other) const
{
return (age == other.age);
}
// 重载小于运算符
bool operator<(const Student& other) const
{
return (age < other.age);
}
int getAge() const
{
return age;
}
};
int main()
{
Student s1(20);
Student s2(18);
Student s3(20);
cout << "s1的年龄: " << s1.getAge() << endl;
cout << "s2的年龄: " << s2.getAge() << endl;
cout << "s3的年龄: " << s3.getAge() << endl;
// 使用重载的等于运算符
if (s1 == s2)
{
cout << "s1 等于 s2" << endl;
}
else
{
cout << "s1 不等于 s2" << endl;
}
if (s1 == s3)
{
cout << "s1 等于 s3" << endl;
}
else
{
cout << "s1 不等于 s3" << endl;
}
// 使用重载的小于运算符
if (s1 < s2)
{
cout << "s1 小于 s2" << endl;
}
else
{
cout << "s1 不小于 s2" << endl;
}
if (s2 < s3)
{
cout << "s2 小于 s3" << endl;
}
else
{
cout << "s2 不小于 s3" << endl;
}
return 0;
}
在上述代码中,我们定义了一个 Student
类,其中包含一个私有的 age
成员变量和对应的访问器函数 getAge()
。
我们重载了等于运算符(==
)和小于运算符(<
)。在重载函数中,我们比较了两个 Student
对象之间的年龄。
在 main
函数中,我们创建了三个 Student
对象 s1
、s2
和 s3
,并输出他们的年龄。
接下来,我们使用重载的等于运算符来比较 s1
和 s2
,以及 s1
和 s3
的年龄是否相等,并输出结果。
然后,我们使用重载的小于运算符来比较 s1
和 s2
,以及 s2
和 s3
的年龄大小,并输出结果。
输出结果如下:
s1的年龄: 20
s2的年龄: 18
s3的年龄: 20
s1 不等于 s2
s1 等于 s3
s1 不小于 s2
s2 小于 s3
函数调用运算符重载
由于重载后的使用的方式非常像函数的调用,因此称为仿函数。
简单例子
#include <iostream>
using namespace std;
class MyFunction
{
public:
int operator()(int a, int b)
{
return a + b;
}
};
int main()
{
MyFunction myFunc;
int result = myFunc(2, 3); // 调用重载的函数调用运算符
cout << "调用结果: " << result << endl;
return 0;
}
在上述代码中,我们定义了一个名为 MyFunction
的类,并重载了函数调用运算符 operator()
。重载后的函数调用运算符将两个参数相加,并返回结果。
在 main
函数中,我们创建了 MyFunction
类的对象 myFunc
。然后,我们将对象 myFunc
当作函数一样进行调用,传递两个参数,并将结果存储在 result
变量中。
输出结果为:
调用结果: 5