详解类与对象——运算符重载

在这里插入图片描述
(^ _ ^)

一.运算符重载概念

运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

二.加号运算符重载

实现两个自定义数据类型相加的运算

  • 不要滥用运算符重载(我不想我的代码可以被其他人直接使用是吧…)
  • 对于内置数据类型的表达式的运算符是不可能改变的
  • 运算符重载也可以发生函数重载
class Person {

public:

    Person() {};

    Person(int a, int b)

    {

        this->m_A = a;

        this->m_B = b;

    }

    //成员函数实现 + 号运算符重载

    Person operator+(const Person& p) {

        Person temp;

        temp.m_A = this->m_A + p.m_A;

        temp.m_B = this->m_B + p.m_B;

        return temp;

    }

  
  

public:

    int m_A;

    int m_B;

};

  

//全局函数实现 + 号运算符重载

//Person operator+(const Person& p1, const Person& p2) {

//  Person temp(0, 0);

//  temp.m_A = p1.m_A + p2.m_A;

//  temp.m_B = p1.m_B + p2.m_B;

//  return temp;

//}

  

//运算符重载 可以发生函数重载

Person operator+(const Person& p2, int val)  

{

    Person temp;

    temp.m_A = p2.m_A + val;

    temp.m_B = p2.m_B + val;

    return temp;

}

  

void test() {

  

    Person p1(10, 10);

    Person p2(20, 20);

  

    //成员函数方式

    Person p3 = p2 + p1;  //相当于 p2.operaor+(p1)

    cout << "mA:" << p3.m_A << " mB:" << p3.m_B << endl;

  
  

    Person p4 = p3 + 10; //相当于 operator+(p3,10)

    cout << "mA:" << p4.m_A << " mB:" << p4.m_B << endl;

  

}

  

int main() {

  

    test();

  

    system("pause");

  

    return 0;

}

三.左移运算符重载

作用:输出自定义的数据类型

class Person {

    friend ostream& operator<<(ostream& out, Person& p);

  

public:

  

    Person(int a, int b)

    {

        this->m_A = a;

        this->m_B = b;

    }

  

    //成员函数 实现不了  p << cout 不是我们想要的效果

    //void operator<<(Person& p){

    //}

  

private:

    int m_A;

    int m_B;

};

  

//全局函数实现左移重载

//ostream对象只能有一个

ostream& operator<<(ostream& out, Person& p) {

    out << "a:" << p.m_A << " b:" << p.m_B;

    return out;

}

  

void test() {

  

    Person p1(10, 20);

  

    cout << p1 << "hello world" << endl; //链式编程

}

  

int main() {

  

    test();

  

    system("pause");

  

    return 0;

}

重载左移运算符配合友元可以实现输出自定义数据类型

四.递增运算符重载

作用: 通过重载递增运算符,实现自己的整型数据


  

class MyInteger {

  

    friend ostream& operator<<(ostream& out, MyInteger myint);

  

public:

    MyInteger() {

        m_Num = 0;

    }

    //前置++

    MyInteger& operator++() {

        //先++

        m_Num++;

        //再返回

        return *this;

    }

  

    //后置++

    MyInteger operator++(int) {

        //先返回

        MyInteger temp = *this; //记录当前本身的值,然后让本身的值加1,但是返回的是以前的值,达到先返回后++;

        m_Num++;

        return temp;

    }

  

private:

    int m_Num;

};

  
  

ostream& operator<<(ostream& out, MyInteger myint) {

    out << myint.m_Num;

    return out;

}

  
  

//前置++ 先++ 再返回

void test01() {

    MyInteger myInt;

    cout << ++myInt << endl;

    cout << myInt << endl;

}

  

//后置++ 先返回 再++

void test02() {

  

    MyInteger myInt;

    cout << myInt++ << endl;

    cout << myInt << endl;

}

  

int main() {

  

    test01();

    //test02();

  

    system("pause");

  

    return 0;

}

总结: 前置递增返回引用,后置递增返回值

五.赋值运算符重载

c++编译器至少给一个类添加4个函数

  1. 默认构造函数(无参,函数体为空)

  2. 默认析构函数(无参,函数体为空)

  3. 默认拷贝构造函数,对属性进行值拷贝

  4. 赋值运算符 operator=, 对属性进行值拷贝

如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题

示例:

class Person

{

public:

  

    Person(int age)

    {

        //将年龄数据开辟到堆区

        m_Age = new int(age);

    }

  

    //重载赋值运算符

    Person& operator=(Person &p)

    {
//先判断是否有属性在堆区,如果有先释放干净,再进行深拷贝
        if (m_Age != NULL)

        {

            delete m_Age;

            m_Age = NULL;

        }

        //编译器提供的代码是浅拷贝

        //m_Age = p.m_Age;

  

        //提供深拷贝 解决浅拷贝的问题

        m_Age = new int(*p.m_Age);

  

        //返回自身

        return *this;

    }

  
  

    ~Person()

    {

        if (m_Age != NULL)

        {

            delete m_Age;

            m_Age = NULL;

        }

    }

  

    //年龄的指针

    int *m_Age;

  

};

  
  

void test01()

{

    Person p1(18);

  

    Person p2(20);

  

    Person p3(30);

  

    p3 = p2 = p1; //赋值操作

  

    cout << "p1的年龄为:" << *p1.m_Age << endl;

  

    cout << "p2的年龄为:" << *p2.m_Age << endl;

  

    cout << "p3的年龄为:" << *p3.m_Age << endl;

}

  

int main() {

  

    test01();

  

    //int a = 10;

    //int b = 20;

    //int c = 30;

  

    //c = b = a;

    //cout << "a = " << a << endl;

    //cout << "b = " << b << endl;

    //cout << "c = " << c << endl;

  

    system("pause");

  

    return 0;

}

六.函数调用运算符重载

  • 因为重载后调用方式十分像函数的调用,所以称作仿函数
  • 仿函数无固定的写法,非常灵活
class MyPrint

{

public:

    void operator()(string text)

    {

        cout << text << endl;

    }

  

};

void test01()

{

    //重载的()操作符 也称为仿函数

    MyPrint myFunc;

    myFunc("hello world");

}

  
  

class MyAdd

{

public:

    int operator()(int v1, int v2)

    {

        return v1 + v2;

    }

};

  

void test02()

{

    MyAdd add;

    int ret = add(10, 10);

    cout << "ret = " << ret << endl;

  

    //匿名对象调用  

    cout << "MyAdd()(100,100) = " << MyAdd()(100, 100) << endl;

}

  

int main() {

  

    test01();

    test02();

  

    system("pause");

  

    return 0;

}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值