运算符重载限制

p387

5.表 11.1 中的大多数运算符都可以通过成员或非成员函数进行重载,但下面的运算符只能通过成员
函数进行重载。
=:赋值运算符。
():函数调用运算符。
[]:下标运算符。
->通过指针访问类成员的运算符。

1.1 重载[]

C++ 规定,下标运算符 []必须以 成员函数的形式进行重载。该重载函数在类中的声明格式如下:

读写方式:

返回值类型 & operator[ ] (参数);

只读模式:

const 返回值类型 & operator[ ] (参数) const;

返回值类型:为此类类型可以实现链式调用。

1.2 头文件

//
// Created by Biter on 2019/10/24.

//
#include
//
// Created by Biter on 2019/10/24.

//
using namespace std;

class Person {
public:

    /**
     * 用来创建 多个 Person对象
     *
     * @param length
     */
    explicit Person(int length = 0);

    /**
     * 列表初始化
     *
     * @param age
     * @param name
     */
    Person(int age, string name);

    /**
     * 初始化一个对象
     *
     * @param person
     */
    Person(Person &person);

    ~Person();

public:
    /**
     * 重载 索引运算符
     * @param i 索引
     * @return 此类对象
     */
    Person &operator[](int i);

    /**
     * 重载赋值运算符
     *
     * @param person
     */
    void operator=(Person &person);

    /**
     * 重载赋值运算符
     *
     * @param age 年龄
     */
    void operator=(int age);

    /**
     * 重载赋值运算符,设置名字
     *
     * @param name 名字
     */
    void operator=(string name);

    /**
     * 重载等于判断运算符,赋值对象
     *
     * @param person
     */
    bool operator==(Person &person);

    /**
     * 重载不等于运算符
     * @param person
     */
    bool operator!=(Person &person);

    /**
     * 输出对象的属性值
     */
    void show() const;

private:
    int m_age{};
    string m_name{};
    int m_length{0};
    Person *m_p;
};

1.3 实现文件

//
// Created by Biter on 2019/10/24.

//
#include "Person.h"

Person::Person(int length) : m_length(length) {
    if (length == 0) {
        m_p = nullptr;
    } else {
        std::cout << "创建对象数组" << std::endl;
        m_p = new Person[length];
        std::cout << "创建对象数组 m_age = " << m_age << "; m_name = " << m_name << "; m_p 地址 = " << m_p << std::endl;
    }
}

Person::Person() {
    m_age = 0;
    m_name = "default";
    std::cout << "默认构造函数 m_age = " << m_age << "; m_name = " << m_name << "; 地址 = " << this << std::endl;
}

Person::Person(Person &person) {
    m_age = person.m_age;
    m_name = person.m_name;
    std::cout << "拷贝构造函数 m_age = " << m_age << "; m_name = " << m_name << "; 地址 = " << this << std::endl;
}

Person::Person(int age, const string name) {
    m_age = age;
    m_name = name;
    std::cout << "列表初始化 m_age = " << m_age << "; m_name = " << m_name << "; 地址 = " << this << std::endl;
}

Person::~Person() {
    if (m_p != nullptr) {
        std::cout << "析构函数 m_age = " << m_age << "; m_name = " << m_name << "; m_p 地址 = " << m_p << std::endl;
        delete[]m_p;
        m_p = nullptr;
    } else{
        std::cout << "析构函数 m_age = " << m_age << "; m_name = " << m_name << "; 地址 = " << this << std::endl;
    }

}

void Person::show() const {
    for (int i = 0; i < m_length; i++) {
        std::cout << "Person[" << i << "].m_age = " << m_p[i].m_age << std::endl;
        std::cout << "Person[" << i << "].m_name = " << m_p[i].m_name << std::endl;
    }
}

Person &Person::operator=(const Person &person) {
    this->m_age = person.m_age;
    m_name = person.m_name;
    std::cout << "赋值运算符 = this->m_age = " << this->m_age << "; this->m_name = " << this->m_name << "  ";
    std::cout << "赋值运算符 = person.m_age = " << person.m_age << "; person.m_name = " << person.m_name << "  ";
    return *this;
}

bool Person::operator==(const Person &person) {
    std::cout << "this->m_age = " << this->m_age << "; this->m_name = " << this->m_name << "  ";
    std::cout << "person.m_age = " << person.m_age << "; person.m_name = " << person.m_name << "  ";
    if ((m_age == person.m_age) && (m_name == person.m_name)) {
        return true;
    } else {
        return false;
    }
}

bool Person::operator!=(const Person &person) {
    std::cout << "this->m_age = " << m_age << "; this->m_name = " << this->m_name << "  ";
    std::cout << "person.m_age = " << person.m_age << "; person.m_name = " << person.m_name << "  ";
    if ((this->m_age != person.m_age) || (this->m_name != person.m_name)) {
        return true;
    } else {
        return false;
    }
}

Person &Person::operator[](int i) {
//    m_p[i].m_age = i;
    std::cout << "数组索引运算符" << std::endl;
    return m_p[i];
}

Person &Person::operator=(int age) {
    m_age = age;
    return *this;
}

Person &Person::operator=(string name) {
    m_name = name;
    return *this;
}

ostream &operator<#include "Person.h"

int main() {
    int mArraySize = 2;

    Person myOperator(mArraySize);
    Person person{23, "biter"};

    Person person1(person);
    myOperator[0] = person;

    myOperator[1] = 1;
    myOperator[1] = "binny";

    myOperator.show();

    std::cout << "是否相等?" << (myOperator[0] == myOperator[1]) << std::endl;
    std::cout << "是否不相等?" << (myOperator[0] != myOperator[1]) << std::endl;
    return 0;
}

问题未解决。

上面这种方式,重载后, m_age输出始终为 0m_name为预期的值。

/**
 * 重载赋值运算符
 *
 * @param age 年龄
 */
Person &operator=(int age);

这种重载赋值运算符, m_age为预期的值, m_name为预期的值。

声明部分:

private:
    int m_age;
    string m_name{};
    int m_length{0};

m_age为基本类型, m_namestring类型。

解决方案

[] 优先级高于 = 。 myOperator[0] = person;先执行 myOperator[0] ,返回这个对象,然后在执行赋值,为myOperator[0] 赋值

out << myOperator[0] << endl;
Person &Person::operator[](int i) {
   //m_p[i].m_age = i;//这条语句,导致我再次调用索引运算符,就把它的值 设置为索引的值了
   return m_p[i];
}

Original: https://www.cnblogs.com/burner/p/yun-suan-fu-zhong-zai-xian-zhi.html
Author: 浪客禅心
Title: 运算符重载限制

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/607445/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【SHELL】在指定格式的文件中查找字符串

    在指定格式的文件中查找字符串 grep -nr "string" –include=*.{c,cpp,h} 在排除指定格式的文件中查找字符串 grep -nr…

    Linux 2023年5月28日
    0129
  • 人人都写过的5个Bug!

    大家好,我是良许。 计算机专业的小伙伴,在学校期间一定学过 C 语言。它是众多高级语言的鼻祖,深入学习这门语言会对计算机原理、操作系统、内存管理等等底层相关的知识会有更深入的了解,…

    Linux 2023年5月27日
    0129
  • Mysql数据库体系

    Mysql数据库体系如下(手绘): 描述: 1.DBMS:database system management是数据库管理软件,平时我们使用的数据库的全称,是C/S架构(clien…

    Linux 2023年6月14日
    097
  • SSH加密原理

    1、SSH初次交换公钥 客户端发起链接请求 服务端返回自己的公钥,以及一个会话ID(这一步客户端得到服务端公钥) 客户端生成密钥对 客户端用自己的公钥异或会话ID,计算出一个值Re…

    Linux 2023年6月7日
    093
  • Debian 开机自动挂载磁盘

    首先要知道自己的磁盘是什么格式的, 常见的有 ext4 Fat32 ntfs exfat ntfs 和 exfat 磁盘格特殊说明, 因为需要额外支持才能挂载. 查看磁盘和分区的命…

    Linux 2023年6月7日
    095
  • 用 shell 脚本制造连接频繁中断的场景

    问题的提出 最近在准备客户端的新版本,在内部灰度过程中,发现一类奇怪的 dump,通过查看日志和堆栈,可以确定是因为每次连上后台就被后台断开了、导致多次重连后随机发生的崩溃。dum…

    Linux 2023年6月6日
    091
  • 等保测评2.0:Windows安全审计

    1、应启用安全审计功能,审计覆盖到每个用户,对重要的用户行为和重要安全事件进行审计 方案: 在管理工具打开本地安全策略,打开路径:安全设置\本地策略\审核策略,将全部审核策略配置为…

    Linux 2023年6月8日
    082
  • redis启动失败 提示Unregistered Authentication Agent for unix-process:6176

    使用宝塔软件安装的redis 一直没启动起来。 使用 journalctl -xe 命令查看原因,发现redis.pid已经存在。 进入该目录,删除redis.pid。 再使用sy…

    Linux 2023年5月28日
    0334
  • rpm简单使用

    rpm描述:利用源码包编译成rpm时,会去指定安装好这个包的位置本质:解压,然后拷贝到相关的目录,然后执行脚本 查询所有已经安装过的包 查看安装位置 解压rpm 查看脚本 查看配置…

    Linux 2023年6月7日
    073
  • 【电子取证:抓包篇】Fiddler 抓包配置与数据分析(简)

    Fiddler 抓包配置与分析(简) 简单介绍了Fiddler抓包常用到的基础知识,看完可以大概明白怎么分析抓包数据 —【suy999】 Fiddler 抓包工具,可以…

    Linux 2023年6月13日
    097
  • LM算法探讨(附python代码)

    1. 案例分析 考虑如下公式: [\gamma_i=\frac{2\pi}{\lambda}\times 2 \sqrt{(x_i-x_p)^2+(y_i-y_p)^2+(z_i-…

    Linux 2023年6月14日
    0144
  • Question06-查询”李”姓老师的数量

    问题比较简单,一个单表查询就可以解决,这里就不过多地讲解 Original: https://www.cnblogs.com/OnlyOnYourself-lzw/p/165738…

    Linux 2023年6月7日
    084
  • Linux CURL的安装和使用

    –获得安装包,从网上直接下载或者其他途径,这里直接wgetwget http://curl.haxx.se/download/curl-7.17.1.tar.gz&#8…

    Linux 2023年6月13日
    084
  • 搭建Redis三主三从集群

    Redis三主三从集群规划 10.0.128.19 使用端口 7000 700110.0.128.22 使用端口 7002 700310.0.128.23 使用端口 7004 70…

    Linux 2023年6月8日
    0105
  • Redis集群的节点通信原理

    Redis集群搭建中,数据如何在节点分布的原理,下面来介绍一下节点之间是如何进行通信(节点握手) 一、基础通讯原理 1、维护集群的元数据的两种方案介绍及对比 在分布式存储中需要提供…

    Linux 2023年5月28日
    0117
  • C语言实现九九乘法口诀表

    儿子六岁了,奶奶在家里给孩子教乘法口诀, 昨天又把大学一年级C语言课程上要求实现的九九乘法口诀表用C语言实现了一遍,代码如下: #include int main() { int …

    Linux 2023年6月13日
    086
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球