运算符重载(前置/后置++、前置/后置--和+=/-=/-/+/=)
来源:互联网 发布:金万维免费域名 编辑:程序博客网 时间:2024/06/05 03:37
特殊运算符
=, [], () 和 -> 操作符只能通过成员函数进行重载
<< 和 >> 操作符最好通过友元函数进行重载
不要重载 && 和 || 操作符,因为无法实现短路规则
#include <stdlib.h>#include <iostream>using namespace std;class Student{public: Student(const char *name,int age) { /*若name为NULL字符串,则申请一个char内存空间,直接赋予0即可*/ if(NULL == name) { m_Pname = new char[1]; m_Pname[0] = '\0'; } /*若name不为NULL,则申请一段内存空间来存储m_Pname*/ m_Pname = new char[strlen(m_Pname) + 1]; strcpy(this->m_Pname,name); this->m_age = age; } Student(){} ~Student() { if (this->m_Pname != NULL) { delete[] this->m_Pname; this->m_Pname = NULL; } }private: char *m_Pname; int m_age;};void test(){ Student s1("lixiaogang",24); Student s2; /*赋值操作*/ s2 = s1;}int main(){ test(); system("pause"); return 0;}
运行代码后会出现严重bug
导致程序直接死掉;原因是因为涉及到了动态内存空间的申请,因此利用C++提供的简单赋值函数不能解决问题,的自己定义一个赋值函数;
I. 重载赋值运算符
#include <stdlib.h>#include <iostream>using namespace std;class Student{public: Student(const char *name,int age) { /*若name为NULL字符串,则申请一个char内存空间,直接赋予0即可*/ if(NULL == name) { m_Pname = new char[1]; m_Pname[0] = '\0'; } /*若name不为NULL,则申请一段内存空间来存储m_Pname*/ m_Pname = new char[strlen(name) + 1]; strcpy(this->m_Pname,name); this->m_age = age; } Student(const Student& s); Student(){} ~Student() { if (this->m_Pname != NULL) { delete[] this->m_Pname; this->m_Pname = NULL; } }public: void display() { cout<<"m_Pname = "<<this->m_Pname<<endl; cout<<"m_age = "<<this->m_age <<endl; } Student& operator=(const Student& s);private: char *m_Pname; int m_age;};Student::Student(const Student& s){ m_Pname = new char[strlen(s.m_Pname) + 1]; strcpy(this->m_Pname,s.m_Pname); this->m_age = s.m_age;}/**** 重载赋值运算符 ****/Student& Student::operator=(const Student& s){ /*1步:若原来的对象有值不为NULL,则先将其内存空间释放掉*/ if (this->m_Pname != NULL) { delete[] this->m_Pname; this->m_Pname = NULL; } /*2步:为对象重新分配s.m_Pname大小的内存空间*/ /*内存大小为strlen(s.n_Pname)+1,要为字符串结束符分配一字节的空间*/ this->m_Pname = new char[strlen(s.m_Pname) + 1]; /*3步:为对象赋值*/ strcpy(this->m_Pname,s.m_Pname); this->m_age = s.m_age; return *this;}void test(){ Student s1("lixiaogang",24); Student s2("hello",22); /*赋值操作*/ s2 = s1; s1.display(); puts("------------"); s2.display();}int main(){ test(); system("pause"); return 0;}
打印结果:
m_Pname = lixiaogangm_age = 24---------------m_Pname = lixiaogangm_age = 24
注意:下列代码中若Student s2("hello",22); 改为Student s2;然后再执行:s2 = s1;
会出现程序死掉的现象;原因在于我的默认构造函数中为空,没有做任何的操作,因此执行赋值操作的时候相当于操作一个野指针,这时去释放一个野指针就会出现错误了。
Student s1("lixiaogang",24); Student s2("hello",22); /*赋值操作*/ s2 = s1;
解决方案是修改默认的构造函数:
Student(){this->m_Pname = NULL;this->m_age = 0;}让其不再执行一个随机的内存空间,这样就不会出现野指针操作的情况。
void test(){ Student s1("lixiaogang",24); Student s2; /*赋值操作*/ s2 = s1; //ok 不会出现问题 s1.display(); puts("------------"); s2.display();}
II.重载前置/后置++、前置/后置 - -
示例代码:
#include <stdlib.h>#include <iostream>using namespace std;class Student{public: //重载运算符<< friend ostream& operator<<(ostream& os,const Student& s); //重载运算符>> friend istream& operator>>(istream& in,Student& s); //重载运算符++(前置) Student& operator++(); //重载运算符++(后置) Student operator++(int); //重载运算符--(前置) Student& operator--(); //重载运算符--(后置) Student operator--(int); //重载运算符+= Student& operator+=(const Student& s); //重载运算符-= Student& operator-=(const Student& s); //重载运算符+ Student operator+(const Student& s); //重载运算符- Student operator-(const Student& s); //普通成员函数 void display();public: //构造函数;初始化列表 Student(int age,int salary):m_age(10),m_salary(salary){} //无参数构造函数 Student(){m_age = 0;m_salary = 1000;} //析构函数 ~Student(){}private: int m_age; int m_salary;}; ostream& operator<<(ostream& os,const Student& s) { os<<"s.m_age = "<<s.m_age<<endl; os<<"s.m_salary = "<<s.m_salary<<endl; return os; } istream& operator>>(istream& in,Student& s) { in>>s.m_age>>s.m_salary; return in; }Student& Student:: operator++(){ ++this->m_age; ++this->m_salary; return *this;}//**************************后置++为了区分前置++与后置++的区别,c++规定了后置++/——操作时,再operator++/operator--后面的括号里加上一个int占位符;用以区别前置与后置的差异;如:operator++(int);operator--(int)//**************************Student Student::operator++(int){ /* Student s_temp; s_temp.m_age = this->m_age; s_temp.m_salary = this->m_salary; m_age++; m_salary++; return s_temp;*/ //和上面代码等价 Student s_temp(*this); this->m_age++; this->m_salary++; return s_temp;}Student& Student::operator--(){ --this->m_age; --this->m_salary; return *this;}Student Student::operator--(int){ Student s_temp; s_temp.m_age = m_age; s_temp.m_salary = m_salary; m_age--; m_salary--; return s_temp; //和下面代码等价 /*Student s_temp(*this); m_age--; m_salary--; return s_temp;*/}Student& Student::operator+=(const Student& s){ this->m_age+=s.m_age; this->m_salary+=s.m_salary; return *this;}Student& Student::operator-=(const Student& s){ this->m_age -= s.m_age; this->m_salary -= s.m_salary; return *this;}Student Student::operator+(const Student& s){ this->m_age += s.m_age; this->m_salary += s.m_salary; return *this;}Student Student::operator-(const Student& s){ /*Student s_temp = *this; s_temp.m_age = this->m_age - s.m_age; s_temp.m_salary = this->m_salary - s.m_salary; return s_temp;*/ //等价 this->m_age -= s.m_age; this->m_salary -= s.m_salary; return *this;}void Student::display(){ cout<<"m_age = "<<m_age<<endl; cout<<"m_salary = "<<m_salary<<endl;}void test(){ Student s1(22,1000); Student s2(11,2000); s2.display(); puts("-----------"); ++s2; s2.display(); puts("-----------"); cout<<s2++<<endl; puts("-----------");}int main(){ test(); system("pause"); return 0;}
0 0
- 运算符重载(前置/后置++、前置/后置--和+=/-=/-/+/=)
- [C++] C++的运算符重载(+、-、前置--、后置--,前置++,后置++、==)
- [C++] C++的运算符重载(+、-、前置--、后置--,前置++,后置++、==)
- 运算符前置++和后置++的重载
- 前置和后置++运算符的重载
- 前置++和后置++重载
- 前置和后置运算符
- 对象前置++,前置--;后置++,后置--(没有利用《和》重载运算符)
- 重载前置++运算符和后置++运算符
- ++运算符的重载前置与后置
- 重载操作符++,区别前置和后置
- 重载 ++ , - - (前置 和 后置)
- 如何重载前置++和后置++
- 关于运算符 前置 ++ 和后置++ (--)
- C++运算符前置后置
- 前置运算 后置运算
- 前置++与后置++重载
- Time类中的运算符重载(3)-前置++,后置++
- Swift CFRunLoop
- Java实现类加载器,加载指定包名下的所有类
- 新建git项目
- Dockerfile 构建镜像
- 基于d3.js简单bubble图
- 运算符重载(前置/后置++、前置/后置--和+=/-=/-/+/=)
- 系统引导流程相关知识
- XAMPP for Linux 实现域名绑定到指定目录
- const 和 #define和stric
- Python's Hardest Problem -- GIL
- 数据结构之跳跃链表
- 山东省第八届ACM大赛I题题解
- 写在设计模式前
- Discuz!论坛教程之批量修改用户组的方法