运算符重载的问题:
运算符重载的本质,运算符的操作数只能是基本的数据类型,但是在实际开发中,开发者往往需要使用符合的数据类型(如结构体,联合等)在C语言中,如果运算符的操作数是复合的数据类型,将是非法操作,C++对运算符的操作数限制进行了扩展,支持复合函数类型的运算。
运算符函数定义的一般格式如下:
数据类型 operator<运算符符号>(<参数表>)
{
<函数体>
}
不可被访问的运算符: 成员运算符 " ." 、成员指针运算符 ” .* "、作用域运算符“ ::”、" sizeof"运算符 和三目运算符“?:”
合法运算符的重载的四个限制规则
(1)重载以后的运算符不能改变运算符的优先级和结合性
(2)重载以后的运算符不能改变运算符操作数的个数及语法结构
(3)重载的运算符操作数至少有一个是自定义类型的
(4)重载运算符函数通常不能有默认的参数。
运算符重载一般有如下两种形式
(1)重载为类的成员函数
(2)重载为类的非成员函数,非成员函数通常为友元
运算符重载函数从原则上讲可以是非成员、非友元的函数,但是定义这样的函数存在很大的弊端,运算符函数访问类的私有和保护成员时,必须使用类的公有接口中提供的设置数据和读取数据的函数,调用这些函数时会降低性能。
成员函数运算符
数据类型 operator<运算符符号>(<参数表>)
{
<函数体>
}
友元函数运算符
friend <函数类型>operator <运算符符号>(<参数表>)
{
<函数体>
}
一般情况下类的成员函数和友元都是可以的,但有些场合,例如 = ()[ ] -> 不能重载类的友元函数,只能重载累的成员函数
<< >>使用友元函数
几种运算符的重载
#include <iostream>
using namespace std;
//单目运算符
class single
{
private :
int num;
public :
single(int num)
{
this -> num = num;
}
~single()
{
}
void print()
{
cout<<"num ="<<num<<endl;
}
single operator++();//单目运算符前置++
single operator++(int);//单目运算符后置++
friend single operator--(single &s);//单目运算符前置--
friend single operator--(single& s, int);//单目运算符后置--
};
//双目运算符
class Complex
{
private:
float i;
float j;
public :
Complex(float i,float j)
{
this-> i = i;
this-> j = j;
}
~Complex()
{}
void print()
{
if(j<0)
{
cout<<i<<j<<"i"<<endl;
}
else
{
cout<<i<<"+"<<j<<"i"<<endl;
}
}
Complex operator+(Complex& s);
Complex operator-(Complex& s);
friend Complex operator*(Complex& ,Complex& );
friend Complex operator/(Complex& ,Complex&);
};
//赋值运算符
class voluation
{
private :
int len;
char *name;
public :
voluation(int len ,char *name)
{
this->len = len;
this->name = new char[len+1];
strcpy(this->name,name);
}
~voluation()
{
if(name !=NULL)
{
len = 0;
delete[]name;
name = NULL;
}
}
voluation(const voluation& s)
{
len = s.len;
name = new char[len+1];
strcpy(name,s.name);
}
void print()
{
cout<<"len ="<<len<<" "<<"name ="<<name<<endl;
}
voluation & operator=(voluation& s);
};
class Array
{
private:
int m_len;
int *str;
public:
Array(int m_len)
{
this->m_len = m_len;
str = new int[m_len+1];
}
~Array()
{
if(str!=NULL)
{
m_len = 0;
delete[]str;
str = NULL;
}
}
void print(int i)
{
cout<<"m_len = "<<m_len<<" str ="<<str[i]<<endl;
}
int &operator[](int index);
friend ostream& operator<<(ostream& o_s,Array& c);
friend istream& operator>>(istream& i_n,Array& c);
};
ostream & operator<<(ostream& o_s,Array& c)
{
o_s<<"____________________________________"<<endl;
for(unsigned int i = 0; i<c.m_len; i++)
{
o_s<<c.str[i]<<endl;
}
o_s<<"____________________________________"<<endl;
}
istream & operator>>(istream& i_n,Array& c)
{
int i;
for(i = 0;i<c.m_len;i++)
{
i_n>>c.str[i];
if(c.str[i]>=100||c.str[i]<=0)
{
return i_n;
}
}
//cout<<endl;
//i_n>>c.str;
return i_n;
}
single single ::operator++()
{
num++;
return *this;
}
single single ::operator++(int)
{
single s(0);
s.num = num;
num++;
return s;
}
single operator--(single& s)
{
s.num--;
return s;
}
single operator--(single& s,int)
{
single a(0);
a.num = s.num;
s.num--;
return a;
}
Complex Complex ::operator +(Complex& s)
{
Complex sum(0,0);
sum.i = i+s.i;
sum.j = j+s.j;
return sum;
}
Complex Complex ::operator -(Complex& s)
{
Complex sub(0,0);
sub.i = i-s.i;
sub.j = j-s.j;
return sub;
}
Complex operator*(Complex& s1,Complex& s2)
{
Complex mux(0,0);
mux.i = s1.i*s2.i-s1.j*s2.j;
mux.j = s1.i*s2.j+s1.j*s2.i;
return mux;
}
Complex operator/(Complex& s1,Complex& s2)
{
Complex del(0,0);
float a;
a = s2.i*s2.i+s2.j*s2.j;
if(a == 0)
{
cout<<"除数错误\n"<<endl;
exit(-1);
}
del.i = (s1.i*s2.i+s1.j*s2.j)/a;
del.j = (s1.j*s2.i-s1.i*s2.j)/a;
return del;
}
voluation& voluation::operator=(voluation &s)
{
if(this->name!=NULL)
{
delete[]name;
len = 0;
}
name = new char[s.len+1];
len = s.len;
strcpy(name,s.name);
return *this;
}
int & Array :: operator[](int index)
{
static int i = 0;
if(index<0||index>=m_len)
{
cout<<"数组越界"<<endl;
exit(-1);
}
str[index] = i++;
return str[index];
}
int main()
{
/*single a(10);
a++;
a.print();
a--;
a.print();
++a;
a.print();
--a;
a.print();
return 0;
*/
/*Complex b(1,3);
Complex c(2,4);
Complex d(0,0);
d = b+c;
d.print();
d= b- c;
d.print();
d = b * c;
d.print();
d = b / c;
d.print();
*/
/*
voluation C1(1,"LYZ");
C1.print();
voluation C2 = C1; //调用拷贝构造函数初始化
C2.print();
voluation C3(2,"YSJ");
C3.print();
C3 = C1; //调用重载后的"="来赋值
C3.print();
*/
/*
Array a(10);
int i;
/*for(i = 0; i< 10 ; i++)
{
a[i] = i+1;
}
cout<<a<<endl;
cin>>a;
cout<<a<<endl;
return 0;
*/
}
String 类函数
string.h
#ifndef _HOMEWORK_H_
#define _HOMEWORK_H_
#include<iostream>
using namespace std;
class MyString
{
friend ostream &operator<<(ostream &out,const MyString &str);
friend istream &operator>>(istream &in,const MyString &str);
public:
MyString(int len = 0);
MyString(const char *p);
MyString(const MyString& str);
~MyString();
public:
MyString& operator=(const char *p);
MyString& operator = (const MyString&str);
char &operator [](const int index);
bool operator == (const char *p) const;
bool operator ==(const MyString& str)const;
bool operator !=(const char *p)const;
bool operator != (const MyString& str)const;
bool operator<(const char *p)const;
bool operator <(const MyString& str)const;
bool operator>(const char *p)const;
bool operator >(const MyString&str)const;
void print();
public:
char *c_str()
{
return m_p;
}
const char *c_str2()
{
return m_p;
}
int length()
{
return m_len;
}
private:
int m_len;
char *m_p;
};
#endif
#include "homework.h"
MyString::MyString(int len )
{
if(len!=0)
{
m_len = len;
m_p = new char[m_len+1];
int i = 0;
for(i = 0;i<m_len;i++)
{
*m_p = '\0';
}
}
else
{
m_len = 0;
m_p = new char[m_len+1];
strcpy(m_p,"\0");
}
}
MyString::MyString(const char *p)
{
if(p!=NULL)
{
m_len = strlen(p);
m_p = new char[m_len+1];
strcpy(m_p,p);
}
else
{
m_len = strlen(p);
m_p = new char [m_len+1];
strcpy(m_p,"\0");
}
}
MyString::MyString(const MyString& str)
{
if(str.m_p !=NULL)
{
m_len = str.m_len;
m_p = new char[m_len+1];
strcpy(m_p,str.m_p);
}
else
{
m_len = 0;
m_p = NULL;
}
}
MyString::~MyString()
{
if(m_p!=NULL)
{
m_len = 0;
delete[]m_p;
}
m_p = NULL;
}
MyString & MyString::operator=(const char *p)
{
if(m_p!=NULL)
{
m_len = 0;
delete[]m_p;
m_p = NULL;
}
if(NULL == p)
{
m_len = 0;
m_p = new char[m_len+1];
strcpy(m_p,"\0");
}
else
{
m_len = strlen(p);
m_p = new char[m_len+1];
strcpy(m_p,p);
}
return *this;
}
MyString& MyString::operator =(const MyString& str)
{
if(m_p!=NULL)
{
m_len = 0;
delete[]m_p;
m_p = NULL;
}
if(NULL == str.m_p)
{
m_len = 0;
m_p = new char[m_len+1];
strcpy(m_p,"\0");
}
else
{
m_len = str.m_len;
m_p = new char[m_len+1];
strcpy(m_p,str.m_p);
}
return *this;
}
char & MyString::operator[](const int index)
{
if(index<0||index>m_len)
{
cout<<"数组越界"<<endl;
exit(-1);
}
else
{
return m_p[index];
}
}
bool MyString::operator==(const char *p)const
{
if(p!=NULL)
{
if(strcmp(m_p,p)!=0)
{
return false;
}
else
{
return true;
}
}
else
{
if(m_len == 0)
{
return true;
}
else
{
return false;
}
}
}
bool MyString::operator==(const MyString & str)const
{
if( str.m_p!=NULL)
{
if(strcmp(m_p,str.m_p)!=0)
{
return false;
}
else
{
return true;
}
}
else
{
if(m_len == 0)
{
return true;
}
else
{
return false;
}
}
}
bool MyString::operator!=(const char *p)const
{
if(p!=NULL)
{
if(strcmp(m_p,p)==0)
{
return false;
}
else
{
return true;
}
}
else
if(m_len != 0)
{
return true;
}
else
{
return false;
}
}
}
bool MyString:: operator!=(const MyString & str)const
{
if( str.m_p!=NULL)
{
if(strcmp(m_p,str.m_p)==0)
{
return false;
}
else
{
return true;
}
}
else
{
if(m_len == 0)
{
return true;
}
else
{
return false;
}
}
}
bool MyString ::operator<(const char *p)const
{
if(p!=NULL)
{
if(strcmp(m_p,p)<0)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
bool MyString:: operator<(const MyString& str) const
{
if(str.m_p!=NULL)
{
if(strcmp(m_p,str.m_p)<0)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
bool MyString ::operator>(const char *p)const
{
if(p!=NULL)
{
if(strcmp(m_p,p)>0)
{
return true;
}
else
{
return false;
}
}
else
{
if(m_len>0)
{
return true;
}
else
{
return false;
}
}
}
bool MyString:: operator>(const MyString& str) const
{
if(str.m_p!=NULL)
{
if(strcmp(m_p,str.m_p)>0)
{
return true;
}
else
{
return false;
}
}
else
{
if(m_len>0)
{
return true;
}
else
{
return false;
}
}
}
ostream &operator<<(ostream &out, const MyString &s1)
{
out<<s1.m_p;
return out;
}
istream &operator>>(istream &in, const MyString &s2)
{
in>>s2.m_p;
return in;
}
void MyString::print()
{
cout<<strlen(m_p)<<endl;
}