C++之=运算符重载

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、必须重载=运算符 (默认=号运算符 是浅拷贝)

注意
成员函数重载=运算符,要先释放this以前指向的空间

if(this->name != NULL)//说明this->name 以前有指向(重点)
        {
            //释放以前指向的空间
            delete [] this->name;
            this->name = NULL;
        }

最后返回 *this代表当前对象。
返回类型为引用,目的是可以迭代操作。

#include <iostream>
#include <cstring>
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++的初学者,或者有一定经验但不太熟悉运算符重载的细节。因此,解释应该清晰,分步骤进行,并包含示例代码以便理解。 首先,得说明运算符重载的基本语法。对于==运算符,通常需要将其声明为类的成员函数,或者作为友元函数。如果是成员函数,参数只有一个,即右侧的对象;而如果是非成员函数,则需要两个参数,左右两侧的对象。这时候要考虑是否要访问类的私有成员,如果需要的话,可能需要声明为友元。 然后,需要提到重载运算符的返回类型。==运算符应该返回bool类型,表示比较的结果是否为真。在实现时,要比较对象的各个相关成员变量是否相等。例如,对于一个简单的Point类,可能需要比较x和y坐标是否都相等。 还要注意const正确性。比较运算符通常不会修改对象的状态,因此应该将成员函数声明为const。同时,参数如果是对象的话,应该使用const引用来避免不必要的拷贝。 接下来,可能需要区分成员函数重载和友元函数重载的情况。比如,当运算符的第一个操作数不是类的实例时,必须使用友元或非成员函数。但对于==来说,通常两种方式都可以,但成员函数更常见。 然后,需要举一个具体的例子,比如一个Point类,展示如何重载==运算符。代码示例应该包括类的定义,运算符重载的实现,以及main函数中的使用示例。这样用户可以看到完整的流程,从定义到使用。 另外,可能需要提到一些常见错误,比如忘记将运算符声明为const,或者没有正确比较所有相关成员变量。还要注意深拷贝和浅拷贝的问题,特别是在类包含指针成员时,需要确保比较的是指针指向的内容而不是地址本身,但可能在基础示例中不需要涉及太复杂的情况。 最后,总结一下步骤:声明运算符函数,实现比较逻辑,确保正确性和效率。可能还需要提到友元函数的使用场景,以及何时选择成员函数或非成员函数形式。 现在需要检查是否有遗漏的部分,比如是否提到返回类型、参数类型、const修饰符,以及示例代码的正确性。确保LaTeX格式的应用符合要求,比如行内公式使用$...$,独立公式使用$$...$$,但在这个问题中可能不需要数学公式,但需要确保代码格式正确,用反引号包裹代码块。 可能还需要提到C++20中的三路比较运算符(<=>)作为扩展知识,但用户的问题集中在==,所以可能不需要深入,但可以简要提及作为额外信息。 总之,结构应该是:介绍运算符重载的概念,==的作用,语法结构,成员函数与友元函数的区别,示例代码,注意事项,常见错误和总结。确保语言简洁,用中文,分步骤,代码正确,并符合用户的要求。</think>在C++中,通过运算符重载可以实现自定义类型的`==`比较逻辑。以下是分步实现方法: --- ### 一、基本语法 `==`运算符重载有两种形式: 1. **成员函数形式** ```cpp bool operator==(const 类名& other) const { // 比较逻辑 } ``` 2. **友元函数形式** ```cpp friend bool operator==(const 类名& a, const 类名& b) { // 比较逻辑 } ``` --- ### 二、实现步骤(以`Point`类为例) #### 1. 定义类结构 ```cpp class Point { private: int x; int y; public: Point(int x, int y) : x(x), y(y) {} // 成员函数形式重载== bool operator==(const Point& other) const { return (x == other.x) && (y == other.y); } // 若选择友元函数形式: // friend bool operator==(const Point& a, const Point& b); }; ``` #### 2. 友元函数实现(可选) ```cpp bool operator==(const Point& a, const Point& b) { return (a.x == b.x) && (a.y == b.y); } ``` --- ### 三、关键注意事项 1. **const修饰符** 必须标记为`const`成员函数,确保不修改对象状态。 2. **参数传递** 使用`const &`传递参数避免拷贝:`const Point& other` 3. **全成员比较** 需比较所有相关成员变量(如`x`和`y`都要参与判断) 4. **对称性要求** 确保`a == b`和`b == a`结果一致 --- ### 四、使用示例 ```cpp int main() { Point p1(3, 4); Point p2(3, 4); Point p3(5, 6); if (p1 == p2) { // 调用重载== std::cout << "p1和p2相等" << std::endl; } if (!(p1 == p3)) { std::cout << "p1和p3不相等" << std::endl; } return 0; } ``` --- ### 五、扩展知识 1. **配套实现`!=`运算符** 可通过`return !(*this == other)`复用代码 2. **C++20三路比较** C++20引入`<=>`运算符可一次性生成`==, !=, <, >`等比较逻辑 --- 通过以上步骤,即可为自定义类型实现符合语义的相等性判断功能。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值