随笔 - 226,  文章 - 0,  评论 - 4,  阅读 - 30140

当自定义类型需要进行运算的时候必须讲运算符进行重载。运算符重载使得编译器给所有的类起了一个通用的运算符名称即operator和运算符组合的形式,这样不同类在重载运算符的时候就有一个通用的名字了。

加号运算符重载

类和基本内置类型相加的实现:

这种情况可以使用全局函数重载和成员函数重载

复制代码
 1 class Person {
 2 public: 
 3     Person operator+(int num) {
 4         Person temp;
 5         temp.a_ = this->a_ + num;
 6         temp.b_ = this->b_ + num;
 7         return temp;
 8     }
 9     int a_;
10     int b_;
11 };
12 void test01() {
13     Person p1;
14     p1.a_ = 10;
15     p1.b_ = 10;
16 
17     Person p3 = p1 + 10;
18     cout << p3.a_ << endl;
19 }
复制代码

输出结果是20

左移运算符的重载:

这个时候只能使用全局函数重载,因为我们想要cout在输出对象的前面,总的来说成员函数重载和成员函数的重载的不同之处在于,成员函数重载你不能控制它的顺序比如cout你必须在对象的左侧,而全局函数的重载可以控制顺序,即第一个参数在第二个参数的左侧。

复制代码
 1 class Person {
 2     friend std::ostream& operator<<(std::ostream& cout, Person& p);
 3 public:
 4     Person(int a, int b) :a_(a), b_(b) {
 5 
 6     }
 7 private:
 8     int a_;
 9     int b_;
10 };
11 std::ostream& operator<<(std::ostream& cout, Person& p) {
12     cout << p.a_ << endl;
13     return cout;
14 }
15 void test01() {
16     Person p(10,20);
17     cout << p << endl;
18 }
复制代码

当函数返回自定义对象时,想要打印这个函数的返回值,重载第二个参数必须用const

举个不恰当的例子:

复制代码
struct student
{
    int age ;
    string name;
};
std::ostream& operator<<(std::ostream& cout, const student& st) {
    cout << st.age << endl;
    cout << st.name << endl;
    return cout;
}
student fun()
{
    student st;
    st.age = 10;
    st.name = "张三";
    return st;
}

int main()
{
    cout << fun() << endl;
    system("Pause");
    return 0;
}
复制代码

如果不加const:

这是因为fun()返回的student是个右值,但是重载的<<,第二个参数是个左值引用,fun()无法绑定到左值引用,改成 const student&就可以绑定到右值了。

前置和后置递增运算符(递减也一样的)

复制代码
1     Myinteger& operator++() {
2         ++num_;
3         return *this;
4     }//前置
5     Myinteger operator++(int) {
6         Myinteger ret = *this;
7         ++num_;
8         return ret;
9     }//后置
复制代码

下面进行几点说明:

  • 后置运算符为什么不返回引用,因为ret是局部对象,不能返回局部对象的引用
  • 从这个地方可以看出来为什么前置是左值,而后置是右值;因为前置返回的是一个引用,引用是左值。而后置在函数执行return语句的时候函数会创建一个临时量,这个临时变量会接收ret的值,因为是临时量所以它是右值。从内置类型的角度来看左值和右值:

这里面后置报错的原因就是因为a加加之后是一个右值而右值不可以修改,而前置加加后是一个左值,左值可以更改。

函数调用运算符

复制代码
 1 class Myprint {
 2 public:
 3     void operator()(string test) {
 4         cout << test << endl;
 5     }
 6     
 7 };
 8 class Myadd {
 9 public:
10     int operator()(int num1, int num2) {
11         return num1 + num2;
12     }
13 };
14 void test01() {
15     Myprint myprint;
16     myprint("hello world"); //由于使用起来非常像一个函数调用因此称为一个仿函数
17 }
18 void test02() {
19     Myadd myadd;
20     int ret = myadd(100, 100);
21     cout << "ret=" << ret << endl;
22     //匿名函数对象,执行过当前行就被释放
23     cout << Myadd()(100, 100) << endl;
24 }
25 
26 int main(){
27     //仿函数特别灵活,没有固定的写法
28     test01();
29     test02();
30     system("pause");
31     return 0;
32 }
复制代码

 

posted on   小凉拖  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示