运算符重载限制
一 重载限制
p387
5.表 11.1 中的大多数运算符都可以通过成员或非成员函数进行重载,但下面的运算符只能通过成员
函数进行重载。
=
:赋值运算符。
()
:函数调用运算符。
[]
:下标运算符。
->
通过指针访问类成员的运算符。
1.1 重载[]
C++ 规定,下标运算符[]
必须以成员函数的形式进行重载。该重载函数在类中的声明格式如下:
读写方式:
返回值类型 & operator[ ] (参数);
只读模式:
const 返回值类型 & operator[ ] (参数) const;
返回值类型
:为此类类型可以实现链式调用。
1.2 头文件
//
// Created by Biter on 2019/10/24.
//
#include <iostream>
//
// 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<<(ostream &os, const Person &person) {
os << "m_age = " << person.m_age << "; m_name = " << person.m_name << endl;
return os;
}
1.4 程序代码
#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;
}
二 问题
问题未解决。
/**
* 重载赋值运算符
*
* @param person
*/
Person &operator=(const Person &person);
上面这种方式,重载后,m_age
输出始终为0
,m_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_name
为string
类型。
解决方案
[] 优先级高于 = 。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];
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)