对已有的运算符赋予多重的含义
扩展c++中提供的运算符的使用范围,以用于不同的类型
运算符重载基本概念
- 运算符重载为普通函数
class Complex{
public:
double real;double imag;
Complex(double r=0.0,double j=0.0){
real=r;imag=j;
}
protected:
private:
};
Complex operator+(const Complex & i1,const Complex & i2){
return Complex(i1.real+i2.real,i1.imag+i2.imag);
}
int main(){
Complex a(1,2),b(3,4),c;
c=a+b;
cout <<c.real<<"--"<<c.imag<<endl;
return 0;
}
输出:
4–6
- 运算符重载为成员函数
class Complex{
public:
Complex(double a=0,double b=0):real(a),imag(b){}
Complex operator+(const Complex & i1);
Complex operator-(const Complex & i1);
void print(){
cout<<real<<"--"<<imag<<endl;
}
protected:
private:
double real,imag;
};
Complex Complex::operator+(const Complex & i1 ){
return Complex(i1.real+real,i1.imag+imag);
}
Complex Complex::operator-(const Complex & i1){
return Complex(i1.real-real,i1.imag-imag);
}
int main(){
Complex a(1,2),b(4,5),c,d;
c=a+b;
d=a-b;
c.print();d.print();
return 0;
}
注意:参数个数为运算符个数-1
- 运算符重载为友元函数
class Complex{
private:
int real,imag;
public:
Complex(int a=0,int b=0):real(a),imag(b){}
void print(){
cout << real << " + i" << imag << endl;
}
friend Complex operator+(const Complex & i1,const Complex & i2);
};
Complex operator+(const Complex & i1,const Complex & i2){
return Complex(i1.real+i2.real,i2.imag+i1.imag);
}
int main(){
Complex a(1,3),b(4,5);
Complex c=a+b;
//d=a-b;
c.print();//d.print();
return 0;
}
赋值运算符重载
例1:
class String{
private:
char *str;
public:
String():str(NULL){}
const char *c_str(){
return str;
}
char *operator=(const char *s);
~String();
};
char *String::operator=(const char *s){
if (str)
delete []str;
if (s){
str=new char[strlen(s)+1];
strcpy(str,s);
}else
str=NULL;
return str;
}
String::~String(){
if (str)
delete []str;
}
int main(){
String s;
s="first";
cout<<s.c_str()<<endl;
s="second";
cout<<s.c_str()<<endl;
return 0;
}
- 浅拷贝
逐个字节拷贝
- 深拷贝
将一个对象中变量所指向的内容,复制到另一个对象中指针成员对象所指的地方
class String{
private:
char *str;
public:
String():str(NULL){}
~String();
const char *string_out(){return str;}
String & operator=(const String & s);
char * operator=(char *s);
};
char* String::operator=(char *s){
if (str)
delete []str;
if (s ){
str=new char[strlen(s )+1];strcpy(str,s );
}else
str=NULL;
return str;
}
String & String::operator=(const String & s){
if (str)
delete []str;
if (s.str){
str=new char[strlen(s.str)+1];strcpy(str,s.str);
}else
str=NULL;
return *this;
}
String::~String(){
if (str)
delete []str;
}
int main(){
String a,b;
a="44";b="33";
cout<<a.string_out()<<endl;
cout<<b.string_out()<<endl;
a=b;cout<<a.string_out()<<endl;
return 0;
}
- 思考1
int main(){
String a,b,c;
a="44";
a=a;
cout<<a.string_out()<<endl;
return 0;
}
程序会出错
正确的程序 :
String& String::operator=(const String & s){
if (str==s.str)
return *this;
if (str)
delete []str;
if (s.str){
str=new char[strlen(s.str)+1];strcpy(str,s.str);
}else
str=NULL;
return *this;
}
- 对operator=的返回值的讨论
void 类型的返回值
a=b=c; 此时程序出错
- 没有引用
1、返回类型如果不是对象的引用:
具体步骤是:
(1)释放元内存资源
(2)申请一块新的内存空间
(3)原堆内存的值赋值到新的内存
(4)创建临时对象(调用拷贝构造函数),返回临时对象
(5)临时对像结束,调用析构函数,释放对象内存
2、返回类型如果是对象的引用:
具体步骤:
(1)释放原内存资源
(2)申请新的内存资源
(3)原值赋值到新的内存
(4)结束
返回对象的引用 不需要调用拷贝构造函数,提高效率,建议采纳。
C++ - 创建动态数组
class CArray{
private:
int size;int *ptr;
public:
CArray(int s=0);
~CArray();
CArray(const CArray & a);
void push_back(int v);
int length(){return size;}
int & operator[](int i);
CArray & operator=(const CArray & a);
};
int & CArray::operator[](int i){
return ptr[i];
}
CArray::CArray(int s){
size=s;
if (s==0){
//delete []ptr;
ptr=NULL;
}else
ptr=new int[s];
}
CArray::~CArray(){
size=0;
if (ptr)
delete []ptr;
}
CArray::CArray(const CArray & a){
if (a.ptr==NULL){
size=0;delete []ptr;ptr=NULL;return;
}
ptr=new int[a.size];size=a.size;
memcpy(ptr,a.ptr,sizeof(int)*a.size);
}
void CArray::push_back(int v){
if (ptr==NULL){
ptr=new int[1];
}else{
int *tem1=new int[size+1];
memcpy(tem1,ptr,sizeof(int)*size);
delete []ptr;ptr=tem1;
}
ptr[size++]=v;
}
CArray & CArray::operator=(const CArray & a){
if (ptr==a.ptr)
return *this;
if (!a.ptr){
if(ptr){
delete []ptr;ptr=NULL;size=0;return *this;
}
}
if (a.ptr){
if (size<a.size){
if(ptr)
delete []ptr;
ptr=new int[a.size];
}
memcpy(ptr,a.ptr,sizeof(int)*a.size);
}
size=a.size;
return *this;
}
int main(int argc, const char * argv[]) {
// insert code here...
CArray a; //开始里的数组是空的
for( int i = 0;i < 5;++i)
a.push_back(i);
CArray a2,a3;
a2 = a;
for( int i = 0; i < a.length(); ++i )
cout << a2[i] << " " ;
a2 = a3; //a2是空的
for( int i = 0; i < a2.length(); ++i ) //a2.length()返回0
cout << a2[i] << " ";
cout << endl;
a[3] = 100;
CArray a4(a);
for( int i = 0; i < a4.length(); ++i )
cout << a4[i] << " ";
return 0;
}
自加自检运算符重载
为待完续