0622 第六讲操作符重载(2)赋值与==运算符重载
一、赋值运算符重载
1、浅拷贝:对象中成员变量的值做一份拷贝,赋值给另一个对象的成员变量
注意:如果成员变量包含指针(空间被分配在堆上),=(浅拷贝),仅仅是把指针的值(所指向变量的地址)赋值给了另一个指针(两个指针指向同一块空间)
1):被赋值的对象堆空间内存泄漏(如果被赋值的对象的指针原本指向一个空间,浅拷贝被赋值后会指向赋值给它的对象的指针,原本的内存泄漏了)
2):两个指针指向同一块空间,对象销毁会造成内存2次删除
3):修改一个对象的成员变量,另一个对象也会发生改变
eg:
Person p1((char*)"111",12),p2((char*)"222",34);
p1.print();//111 12
p2.print();///222 34
p1=p2;//p1对象成员变量指针name内存泄漏
p1.print();//222 34
p2.print();//222 34
p1.setName((char*)"abc");//修改
p1.print();//abc 34
p2.print();//abc 34
2、深拷贝:
赋值匀速符重载(深拷贝) 必须使用成员函数的形式编写
1、避免自赋值
2、删除旧空间
3、开辟新空间
4、赋值
5、return *this(函数链)
3、练习
1)深拷贝练习:
eg:
Person.hpp
#ifndef person_hpp
#define person_hpp
#include <stdio.h>
class Person
{
private:
char *name;
char sex[6];
int age;
char hobby[20];
public:
~Person();
Person();
Person(char *_name,char *_sex,int _age,char *_hobby);
void setPerson(char *_name,char *_sex,int _age,char *_hobby);
void print();
void setName(char *name);
Person& operator=(Person& p);
};
#endif
Person.cpp
#include "person.hpp"
#include "iostream"
#include "string"
using namespace std;
Person& Person:: operator=(Person& p)
{
if (this != &p) {
delete [] this->name;
this->name=NULL;
name=new char [strlen(p.name)+1];
strcpy(this->name ,p.name);
strcpy(this->sex ,p.sex);
this->age=p.age;
strcpy(this->hobby ,p.hobby);
}
return *this;
}
Person::~Person()
{
if (name!=NULL) {
delete []name;
name=NULL;
}
cout<<"调用CPerson析构函数"<<endl;
}
Person::Person()
{
name=new char (1);
strcpy(name, "");
strcpy(sex, "");
age=0;
strcpy(hobby, "");
}
Person::Person(char *_name,char *_sex,int _age,char *_hobby)
{
name=new char[strlen(_name)+1];
strcpy(name, _name);
strcpy(sex, _sex);
age=_age;
strcpy(hobby, _hobby);
}
void Person::setPerson(char *_name,char *_sex,int _age,char *_hobby)
{
strcpy(name, _name);
strcpy(sex, _sex);
age=_age;
strcpy(hobby, _hobby);
}
void Person::print()
{
cout<<"姓名:\t" <<name<<"\t性别:\t"<<sex<<"\t年龄:\t"<<age<<"\t爱好:\t"<<hobby<<endl;
}
void Person::setName(char *name)
{
strcpy(this->name, name);
}
main.cpp
#include "person.hpp"
#include "iostream"
#include "string"
using namespace std;
int main(int argc, const char * argv[]) {
Person p1((char*)"lily",(char*)"女",10,(char*)"打豆豆"),p2((char*)"jiji",(char*)"女",11,(char*)"打��");
p1.print();
p2.print();
p1=p2;
p1.print();
p2.print();
p1.setName((char*)"abc");
p1.print();
p2.print();
cout<<"pause"<<endl;
return 0;
}
姓名: lily 性别: 女 年龄: 10 爱好: 打豆豆
姓名: jiji 性别: 女 年龄: 11 爱好: 打��
姓名: jiji 性别: 女 年龄: 11 爱好: 打��
姓名: jiji 性别: 女 年龄: 11 爱好: 打��
姓名: abc 性别: 女 年龄: 11 爱好: 打��
姓名: jiji 性别: 女 年龄: 11 爱好: 打��
pause
调用CPerson析构函数
调用CPerson析构函数
Program ended with exit code: 0
2)重载运算符练习:
编写字符串类:MyString
成员变量:char *str;
函数:
1、默认构造函数
2、有一个参数的构造函数
3、析构函数
4、<<运算符重载
5、+运算符重载
6、+= 运算符重载
7、==运算符重载
8、=运算符重载
9、[]运算符重载(两个)
10、const char& at(int index)const
11、char& at(int index)
12、>运算符重载
MyString.hpp
#ifndef MyString_hpp
#define MyString_hpp
#include <iostream>
using namespace std;
class MyString
{
friend ostream& operator<<(ostream &out,const MyString &ms);
private:
char *str;
public:
MyString();
MyString(char *_str);
~MyString();
MyString operator +(const MyString &ms);
void operator +=(const MyString &ms);
int operator ==(const MyString &ms);
void operator =(const MyString &ms);
const char operator [](const int index)const;
char operator [](int index);
const char& at(int index)const;
char& at(int index);
int operator >(const MyString &ms);
};
#include <stdio.h>
#endif
MyString.cpp
#include "MyString.hpp"
#include <string>
using namespace std;
ostream& operator<<(ostream &out,const MyString &ms)
{
out<<ms.str<<endl;
return out;
}
MyString:: MyString()
{
str=new char[20];
}
MyString::MyString(char *_str)
{
str=new char[strlen(_str)+1];
strcpy(str, _str);
}
MyString::~MyString()
{
if (str!=NULL) {
delete []str;
str=NULL;
}
}
MyString MyString::operator +(const MyString &ms)
{
MyString temp;
temp.str=new char[strlen(str)+strlen(ms.str)+1];
strcat(temp.str, str);
strcat(temp.str, ms.str);
return temp;
}
void MyString::operator +=(const MyString &ms)
{
char *temp=str;
str=new char[strlen(temp)+strlen(ms.str)+1];
strcat(str, temp);
strcat(str, ms.str);
delete temp;
}
int MyString::operator ==(const MyString &ms)
{
if (strcmp(str, ms.str)) {
return 0;
}
return 1;
}
void MyString::operator =(const MyString &ms)
{
delete []str;
str=new char[strlen(ms.str)+1];
strcpy(str, ms.str);
}
const char MyString::operator [](const int index)const
{
return str[index];
}
char MyString::operator [](int index)
{
return str[index];
}
const char& MyString::at(int index)const
{
return str[index];
}
char& MyString::at(int index)
{
return str[index];
}
int MyString::operator >(const MyString &ms)
{
return strcmp(str, ms.str);
}
main.cpp
int main(int argc, const char * argv[]) {
MyString str1((char*)"abc"),str2((char*)"def"),str3((char*)"");
str3=str1+str2;
cout<<"str1 = "<<str1;
cout<<"str2 = "<<str2;
cout<<"str3 = "<<str3;
cout<<"str2[0] = "<<str3[0]<<endl;
str1+=str2;
cout<<"str1 = "<<str1;
cout<<"str2 = "<<str2;
cout<<(str1==str2)<<endl;
cout<<(str2>str1)<<endl;
return 0;
}
str1 = abc
str2 = def
str3 = abcdef
str2[0] = a
str1 = abcdefabcdef
str2 = def
0
3
Program ended with exit code: 0