37_重载=运算符

前提1:类中 没有指针成员 不需要重载=运算符(默认的浅拷贝就可以完成)

#include <iostream>

using namespace std;
class Person
{
private:
    int a;
    int b;
public:
    Person():a(0),b(0)
    {
        cout<<"无参构造"<<endl;
    }
    Person(int a, int b):a(a),b(b)
    {
        cout<<"有参构造"<<endl;
    }
    void showPerson(void)
    {
        cout<<"a = "<<a<<", b = "<<b<<endl;
    }
    ~Person()
    {
        cout<<"析构函数"<<endl;
    }
};
void test01()
{
    Person ob1(10,20);
    ob1.showPerson();

    //注意 旧对象 给新对象赋值 调用的是拷贝构造(默认拷贝构造就是单纯的赋值)
    Person ob2 = ob1;//这个地方 可不是调用赋值=运算符
    ob2.showPerson();

    Person ob3;
    ob3 = ob1;//此处才是调用的赋值=运算符(默认赋值=运算是浅拷贝) 
    ob3.showPerson();
}
int main(int argc, char *argv[])
{
    test01();
    return 0;
}

运行结果:

前提2:类中 有指针成员 必须重载=运算符

指针作为类的成员:

1、拷贝构造函数 必须自定义(默认拷贝构造 是浅拷贝)

2、必须重载=运算符 (默认=号运算符 是浅拷贝)

#include <iostream>
#include<string.h>
using namespace std;
class Person
{
private:
    char *name;//指针成员
public:
    Person()
    {
        name = NULL;
        cout<<"无参构造"<<endl;
    }
    Person(char *name)
    {
        //根据实际传入的 参数 给this->name申请空间
        this->name = new char[strlen(name)+1];

        //将name指向的字符串 拷贝到  this->name指向的空间中
        strcpy(this->name,name);

        cout<<"有参构造"<<endl;
    }
    Person(const Person &ob)//ob代表的就是旧对象
    {
        //this代表的是新对象
        cout<<"拷贝构造函数"<<endl;
        this->name = new char[strlen(ob.name)+1];
        strcpy(this->name, ob.name);
    }


    ~Person()
    {
        cout<<"析构函数"<<endl;
        if(this->name != NULL)
        {
            delete [] this->name;
            this->name = NULL;
        }
    }

    void showPerson(void)
    {
        cout<<"name = "<<name<<endl;
    }
    //成员函数 重载=运算符
    Person& operator=(Person &ob)//ob == ob1
    {
        //this ==>&ob3
        if(this->name != NULL)//说明this->name 以前有指向(重点)
        {
            //释放以前指向的空间
            delete [] this->name;
            this->name = NULL;
        }

        //申请空间
        this->name = new char[strlen(ob.name)+1];
        //拷贝内容
        strcpy(this->name,ob.name);

        return *this;//重点
    }
};

void test01()
{
    Person ob1("lucy");
    ob1.showPerson();

    Person ob2 = ob1;//调用拷贝构造

    Person ob3("bob");
    //不重载 = 默认是浅拷贝
    ob3 = ob1;

    ob3.showPerson();

    Person ob6,ob5,ob4;
    ob6 = ob5 = ob4 = ob1;
    ob6.showPerson();
}
int main(int argc, char *argv[])
{
    test01();
    return 0;
}

运行结果:

 

<think>嗯,用户想了解C++中如何重载等于运算符,特别是运算符=重载示例。首先,我需要回忆一下C++中运算符重载的基本规则。等于运算符通常指的是赋值运算符=和相等判断运算符==,但用户的问题里提到“等于运算符”,可能需要明确区分这两个。不过根据用户后面的示例请求,可能两者都需要涉及。 首先,看看用户提供的引用内容。引用1中提到了-=和+=运算符重载,展示了如何通过成员函数来重载这些运算符,返回当前对象的引用。引用2和3则讨论了==和!=重载,特别是引用3中的MyString类重载==运算符,比较了字符串内容和两个整数成员变量。这说明用户可能对如何正确重载这两个运算符感兴趣。 用户的问题中提到“运算符= 重载”,通常赋值运算符=重载是用于对象之间的赋值操作,而==则是用于比较两个对象是否相等。需要确认用户是否混淆了这两个,或者确实想同时了解。根据问题中的关键词“等于运算符”和示例请求,可能用户需要同时了解赋值运算符=和相等运算符==重载,但需要进一步明确。 接下来,我需要组织回答的结构。首先,区分赋值运算符=和相等运算符==,然后分别给出示例。根据引用3中的例子,可以展示如何重载==运算符,而引用1中的例子展示了如何返回*this,这可能适用于赋值运算符重载。 赋值运算符=重载需要注意深拷贝和浅拷贝的问题,特别是在有指针成员的情况下。例如,在MyString类中,szStr是一个指针,进行赋值时需要进行深拷贝,否则会导致内存问题。而相等运算符==则需要比较对象的内容是否相同。 需要确保示例代码正确,符合C++语法,比如运算符重载的返回类型、参数类型是否正确。例如,赋值运算符通常返回当前对象的引用,而相等运算符返回bool类型。 用户提供的引用中有关于数组类和MyString类的例子,可以参考这些结构来构建示例。例如,在重载赋值运算符时,需要处理自我赋值的情况,并正确释放原有资源,然后进行深拷贝。 可能还需要提到拷贝构造函数和析构函数的重要性,因为在涉及资源管理(如动态内存)时,这三个函数(拷贝构造、拷贝赋值、析构)通常需要同时实现,称为Rule of Three。 总结回答的结构:首先介绍赋值运算符=和相等运算符==的区别,然后分别给出重载的示例,说明注意事项,如深拷贝、返回类型、参数类型,以及自我赋值检查等。同时,结合用户提供的引用中的代码示例,展示如何在类中实现这些运算符重载。 需要确保回答使用中文,代码示例正确,并符合用户要求的格式,如行内公式使用$...$,独立公式用$$...$$,但在这个问题中可能不需要数学公式,但需要注意LaTeX语法正确。不过用户的问题主要是代码示例,所以重点放在代码的正确性和解释上。 可能生成的相关问题包括:如何区分赋值和相等运算符重载?为什么需要处理自我赋值?深拷贝和浅拷贝在运算符重载中的作用?等等。这些问题可以帮助用户进一步理解相关概念。 最后,检查是否有遗漏,比如用户是否还需要其他运算符重载示例,或者关于运算符重载的其他注意事项,如友元函数与成员函数的选择,运算符重载的限制等。但根据用户的问题,集中在等于运算符和赋值运算符上,所以应保持回答的针对性。</think>### C++等于运算符重载详解 在C++中,运算符重载分为两种类型: 1. **赋值运算符 `=`**:用于对象间的赋值操作 2. **相等判断运算符 `==`**:用于比较两个对象是否相等 --- ### 一、赋值运算符 `=` 重载 #### 核心要点 - **必须返回当前对象引用**:`ClassName& operator=()` - **处理自我赋值**:避免资源释放导致错误 - **深拷贝需求**:当类包含指针成员时 #### 示例代码(含指针成员) ```cpp class MyString { private: char* data; int length; public: // 赋值运算符重载 MyString& operator=(const MyString& other) { if (this != &other) { // 自我赋值检查 delete[] data; // 释放旧资源 length = other.length; data = new char[length + 1]; strcpy(data, other.data); } return *this; // 返回当前对象 } }; ``` --- ### 二、相等运算符 `==` 重载 #### 实现方式对比 | 方式 | 成员函数重载 | 友元函数重载 | |-----------|----------------------------------|-----------------------------------| | 语法特点 | 隐含`this`指针 | 需要显式声明两个参数 | | 适用场景 | 对称性要求不高的操作 | 需要支持左右操作数类型转换的场景 | | 访问权限 | 可直接访问私有成员 | 需要类授权`friend`声明 | #### 成员函数实现示例 ```cpp class Vector3D { public: float x, y, z; bool operator==(const Vector3D& other) const { return (x == other.x) && (y == other.y) && (z == other.z); } }; ``` #### 友元函数实现示例 ```cpp class Complex { private: double real, imag; public: friend bool operator==(const Complex& c1, const Complex& c2); }; bool operator==(const Complex& c1, const Complex& c2) { return (c1.real == c2.real) && (c1.imag == c2.imag); } ``` --- ### 三、关键注意事项 1. **三法则(Rule of Three)**:若重载了赋值运算符,应同时实现 - 析构函数 - 拷贝构造函数 - 拷贝赋值运算符 2. **返回类型规范**: - `=` 返回`ClassName&`(支持链式赋值) - `==` 返回`bool` 3. **常量正确性**: ```cpp bool operator==(const MyClass& other) const; // 注意const修饰 ``` --- ### 四、完整类示例(含`=`和`==`) ```cpp class Person { private: char* name; int age; public: // 赋值运算符 Person& operator=(const Person& p) { if (this != &p) { delete[] name; age = p.age; name = new char[strlen(p.name)+1]; strcpy(name, p.name); } return *this; } // 相等运算符(成员函数版) bool operator==(const Person& p) const { return (age == p.age) && (strcmp(name, p.name) == 0); } }; ``` --- ### 性能优化建议 1. **使用移动语义**(C++11+):通过`std::move`优化资源转移 2. **返回值优化**(RVO):利用编译器优化减少拷贝 3. **哈希支持**:重载`==`时建议同时实现`std::hash`特化 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值