类和对象(高级)
一、运算符重载
运算符重载是对已有的运算符 指定新功能。不能创建新运算。
运算符重载关键字operator
思路:
1、弄懂运算符的运算对象的个数。(个数决定了 重载函数的参数个数)
2、识别运算符左边的运算对象 是类的对象还是其他.
类的对象:成员函数实现(推荐,少一个参数),全局函数实现(不推荐)
其他:只能是全局函数实现
1、重载<<运算符(全局函数实现)
#include <iostream>
#include<string>
using namespace std;
class Person{
friend ostream& operator <<(ostream &out,Person &ob );
private:
int num;
string name;
float score;
public:
Person(){}
Person(int num,string name,float score):num(num),name(name),score(score){
}
};
//返回cout的引用类型(可以链式输出)
ostream& operator <<(ostream &out,Person &ob ){
out<<ob.num<<" "<<ob.name<<" "<<ob.score;
return out;
}
int main(int argc, char *argv[])
{
Person lucy(100,"lucy",19.2f);
Person bob(102,"bob",19.3f);
cout<<lucy<<endl;
//链式 输出
cout<<lucy<<bob<<endl;
return 0;
}
2、重载输入>>运算符
#include <iostream>
#include<string>
using namespace std;
class Person{
friend ostream& operator<<(ostream &out,Person &ob );
friend istream& operator>>(istream &in,Person &ob);
private:
int num;
string name;
float score;
public:
Person(){}
Person(int num,string name,float score):num(num),name(name),score(score){
}
};
//返回cout的引用类型(可以链式输出)
ostream& operator<<(ostream &out,Person &ob ){
out<<ob.num<<" "<<ob.name<<" "<<ob.score;
return out;
}
istream &operator>>(istream &in,Person &ob){
in>>ob.num>>ob.name>>ob.score;
return in;
}
int main(int argc, char *argv[])
{
Person lucy;
cin>>lucy;
cout<<lucy<<endl;
return 0;
}
如果使用全局函数 重载运算符 必须将全局函数设置成友元。
3、可以重载的运算符
4、重载加法运算符+(全局函数实现)
#include <iostream>
#include<string>
using namespace std;
class Person{
friend ostream& operator<<(ostream &out,Person ob );
friend istream& operator>>(istream &in,Person &ob);
friend Person operator +(Person ob1,Person ob2);
private:
int num;
string name;
float score;
public:
Person(){}
Person(int num,string name,float score):num(num),name(name),score(score){
}
};
//返回cout的引用类型(可以链式输出)
ostream& operator<<(ostream &out,Person ob ){
out<<ob.num<<" "<<ob.name<<" "<<ob.score;
return out;
}
istream &operator>>(istream &in,Person &ob){
in>>ob.num>>ob.name>>ob.score;
return in;
}
//返回值不能为引用,因为temp是局部变量
Person operator +(Person ob1,Person ob2){
Person temp;
temp.num=ob1.num+ob2.num;
temp.name=ob1.name+ob2.name;
temp.score=ob1.score+ob2.score;
return temp;
}
int main(int argc, char *argv[])
{
Person lucy(100,"lucy", 88.8f);
Person bob(101,"bob", 99.9f);
Person tom(102,"tom", 77.7f);
cout<<lucy+bob+tom<<endl;
return 0;
}
5、重载加法运算符+(成员函数实现 推荐)
#include <iostream>
#include<string>
using namespace std;
class Person{
friend ostream& operator<<(ostream &out,Person ob );
friend istream& operator>>(istream &in,Person &ob);
private:
int num;
string name;
float score;
public:
Person(){}
Person(int num,string name,float score):num(num),name(name),score(score){
}
//成员函数实现重载
Person operator +(Person ob2){
Person temp;
temp.num=this->num+ob2.num;
temp.name=this->name+ob2.name;
temp.score=this->score+ob2.score;
return temp;
}
};
//返回cout的引用类型(可以链式输出)
ostream& operator<<(ostream &out,Person ob ){
out<<ob.num<<" "<<ob.name<<" "<<ob.score;
return out;
}
istream &operator>>(istream &in,Person &ob){
in>>ob.num>>ob.name>>ob.score;
return in;
}
int main(int argc, char *argv[])
{
Person lucy(100,"lucy", 88.8f);
Person bob(101,"bob", 99.9f);
Person tom(102,"tom", 77.7f);
cout<<lucy+bob+tom<<endl;
return 0;
}
6、重载==运算符(成员函数实现 推荐)
#include <iostream>
#include<string>
using namespace std;
class Person{
friend ostream& operator<<(ostream &out,Person ob );
friend istream& operator>>(istream &in,Person &ob);
private:
int num;
string name;
float score;
public:
Person(){}
Person(int num,string name,float score):num(num),name(name),score(score){
}
Person operator +(Person ob2){
Person temp;
temp.num=this->num+ob2.num;
temp.name=this->name+ob2.name;
temp.score=this->score+ob2.score;
return temp;
}
//成员函数重载==运算符
bool operator ==(Person &ob){
if(num==ob.num&&name==ob.name&&score==ob.score){
return true;
}
else{
return false;
}
}
};
//返回cout的引用类型(可以链式输出)
ostream& operator<<(ostream &out,Person ob ){
out<<ob.num<<" "<<ob.name<<" "<<ob.score;
return out;
}
istream &operator>>(istream &in,Person &ob){
in>>ob.num>>ob.name>>ob.score;
return in;
}
int main(int argc, char *argv[])
{
Person lucy(100,"lucy", 88.8f);
// Person bob(101,"bob", 99.9f);
Person bob(100,"lucy", 88.8f);
if(lucy==bob){
cout<<"相等"<<endl;
}
else{
cout<<"不相等"<<endl;
}
return 0;
}
7、重载++运算符
++a(前置++),它就调用operator++(a),
a++(后置++),它就会去调用operator++(a,int)
案例1:重载后置++
类名称 operator++(int)
{
old=//先保存旧的值
//自增++
return old;//返回旧值
}
#include <iostream>
#include<string>
using namespace std;
class Person{
friend ostream& operator<<(ostream &out,Person ob );
friend istream& operator>>(istream &in,Person &ob);
private:
int num;
string name;
float score;
public:
Person(){}
Person(int num,string name,float score):num(num),name(name),score(score){
}
Person operator +(Person ob2){
Person temp;
temp.num=this->num+ob2.num;
temp.name=this->name+ob2.name;
temp.score=this->score+ob2.score;
return temp;
}
bool operator ==(Person &ob){
if(num==ob.num&&name==ob.name&&score==ob.score){
return true;
}
else{
return false;
}
}
//后置++
Person operator ++(int a){
Person old;
old.num=num;
old.name=name;
old.score=score;
num+=1;
name+=name;
score+=score;
return old;
}
};
//返回cout的引用类型(可以链式输出)
ostream& operator<<(ostream &out,Person ob ){
out<<ob.num<<" "<<ob.name<<" "<<ob.score;
return out;
}
istream &operator>>(istream &in,Person &ob){
in>>ob.num>>ob.name>>ob.score;
return in;
}
int main(int argc, char *argv[])
{
Person lucy(100,"lucy", 88.8f);
Person bob;
//先使用后++
bob = lucy++;
cout<<bob<<endl;
cout<<lucy<<endl;
return 0;
}
案例2:重载前置++
#include <iostream>
#include<string>
using namespace std;
class Person{
friend ostream& operator<<(ostream &out,Person ob );
friend istream& operator>>(istream &in,Person &ob);
private:
int num;
string name;
float score;
public:
Person(){}
Person(int num,string name,float score):num(num),name(name),score(score){
}
Person operator +(Person ob2){
Person temp;
temp.num=this->num+ob2.num;
temp.name=this->name+ob2.name;
temp.score=this->score+ob2.score;
return temp;
}
bool operator ==(Person &ob){
if(num==ob.num&&name==ob.name&&score==ob.score){
return true;
}
else{
return false;
}
}
Person operator ++(int a){
Person old;
old.num=num;
old.name=name;
old.score=score;
num+=1;
name+=name;
score+=score;
return old;
}
//前置++
Person operator ++(){
num+=1;
name+=name;
score+=score;
return *this;//返回自身的值
}
};
//返回cout的引用类型(可以链式输出)
ostream& operator<<(ostream &out,Person ob ){
out<<ob.num<<" "<<ob.name<<" "<<ob.score;
return out;
}
istream &operator>>(istream &in,Person &ob){
in>>ob.num>>ob.name>>ob.score;
return in;
}
int main(int argc, char *argv[])
{
Person lucy(100,"lucy", 88.8f);
Person bob;
//先++ 后使用
bob = ++lucy;
cout<<bob<<endl;
cout<<lucy<<endl;
// bob等于lucy
return 0;
}
8、重载()运算符
重载()运算符 一般用于 为算法 提供策略。
#include <iostream>
using namespace std;
class Print{
public:
void operator()(char *str){
cout<<str<<endl;
}
};
int main()
{
Print ob;
//对象和()结合 触发operator()成员函数 调用
ob("Hello World");
//匿名成员
Print()("hello world");
return 0;
}
二、自定义string类
重载构造函数
#include <iostream>
#include<string.h>
using namespace std;
class MyString{
private:
int size;
char *str;
public:
MyString();//无参构造
MyString(char *str);//带参构造
MyString(const MyString &ob);//深拷贝
~MyString();//析构函数
};
MyString::MyString(){
str=NULL;
size=0;
}
MyString::MyString(char *str){
size=strlen(str);
this->str=new char[size+1];
memset(this->str,0,size+1);
strcpy(this->str,str);
}
MyString::MyString(const MyString &ob){
size=ob.size;
str=new char[size+1];
memset(str,0,size+1);
strcpy(str,ob.str);
}
MyString::~MyString(){
if(str!=NULL){
delete[]str;
str=NULL;
}
}
int main(int argc, char *argv[])
{
return 0;
}
重载输入输出(全局函数实现)
设为友元函数
friend ostream& operator<<(ostream &out,MyString ob);
friend istream& operator >>(istream &in,MyString &ob);
全局函数实现
ostream& operator<<(ostream &out,MyString ob){
out<<ob.str;
return out;
}
istream& operator >>(istream &in,MyString &ob){
char buff[1024]="";
cin>>buff;
if(ob.str!=NULL){
delete[]ob.str;
ob.str=NULL;
}
ob.size=strlen(buff);
ob.str=new char[ob.size+1];
memset(ob.str,0,ob.size+1);
strcpy(ob.str,buff);
return in;
}
重载括号运算符
类中声明,类外定义
char& MyString::operator [](int pos){
if(pos<0||pos>=size){
cout<<"元素位置不合法"<<endl;
exit(-1);
}
return str[pos];
}
重载+运算符
类外实现
MyString MyString::operator +(MyString ob){
MyString temp;
temp.size=size+ob.size;
temp.str=new char[temp.size+1];
memset( temp.str,0,temp.size+1);
strcpy(temp.str,str);
strcat(temp.str,ob.str);
return temp;
}
MyString MyString::operator +(char *str)
{
MyString temp;
temp.size=this->size+strlen(str);
temp.str=new char[temp.size+1];
memset(temp.str,0,temp.size+1);
strcpy(temp.str,this->str);
strcat(temp.str,str);
return temp;
}
重载=赋值运算符(深拷贝)
MyString &MyString::operator =(MyString ob)
{
if(this->str!=NULL){
delete[]this->str;
this->str=NULL;
}
this->size=ob.size;
this->str=new char[this->size+1];
memset(this->str,0,this->size+1);
strcpy(this->str,ob.str);
return *this;
}
MyString &MyString::operator =(char *str)
{
if(this->str!=NULL){
delete[]this->str;
this->str=NULL;
}
this->size=strlen(str);
this->str=new char[this->size+1];
memset(this->str,0,this->size+1);
strcpy(this->str,str);
return *this;
}
重载>运算符
bool MyString::operator>(MyString ob)
{
if(str==NULL||ob.str==NULL){
exit(-1);
}
if(strcmp(this->str,ob.str)>0){
return true;
}
else{
return false;
}
}
bool MyString::operator >(char *str)
{
if(str==NULL||this->str==NULL){
exit(-1);
}
if(strcmp(this->str,str)>0){
return true;
}
else{
return false;
}
}
三、智能指针
智能指针:解决 堆区空间的对象释放问题
前言:
#include <iostream>
using namespace std;
class Data{
public:
Data(){
cout<<"无参构造"<<endl;
}
~Data(){
cout<<"析构函数"<<endl;
}
void func(){
cout<<"func函数"<<endl;
}
};
int main()
{
Data *ob=new Data();//通过new申请堆区空间
return 0;
}
结果:只打印了无参构造,并没有调用析构函数
无参构造
设置智能指针
#include <iostream>
using namespace std;
class Data{
public:
Data(){
cout<<"无参构造"<<endl;
}
~Data(){
cout<<"析构函数"<<endl;
}
void func(){
cout<<"func函数"<<endl;
}
};
class SmartPointer{
private:
Data *p;
public:
SmartPointer(){}
SmartPointer(Data *p){
this->p=p;
}
~SmartPointer(){
delete p;
}
};
int main()
{
SmartPointer ob(new Data);
return 0;
}
无参构造
析构函数
结果是调用了析构函数,运用的原理就是生命周期
我们在类中
//重载*运算符
Data& operator*(){
return *p;
}
//重载->运算符
Data* operator->(){
return p;
}
#include <iostream>
using namespace std;
class Data{
public:
Data(){
cout<<"无参构造"<<endl;
}
~Data(){
cout<<"析构函数"<<endl;
}
void func(){
cout<<"func函数"<<endl;
}
};
class SmartPointer{
private:
Data *p;
public:
SmartPointer(){}
SmartPointer(Data *p){
this->p=p;
}
~SmartPointer(){
delete p;
}
//重载*运算符
Data& operator*(){
return *p;
}
//重载->运算符
Data* operator->(){
return p;
}
};
int main()
{
SmartPointer ob(new Data);
//访问通过SmartPointer访问p
ob.operator *().func();
ob.operator->()->func();
(*ob).func();
ob->func();
return 0;
}