编程爱好者联盟 2016-09-30
不是所有的运算符都能重载, 以下的都不行 :: 作用域运算符号 . 成员访问运算符 .* 成员指针解引用 sizeof 求类型或者对象大小的运算符 ?: 三目运算符 typei类型信息运算符 写重载时注意:
clasFraction{
inx;
iny;
public:
Fraction(inx=int y=1):x(x),y(y){}
voishow(){
cout<<x<<'/'<<y<<endl;
}
//成员形式的运算符重载,this充当第一个参数,且可以省略
Fractiooperator+(const Fraction& fb)const{ //有这个的话不能和全局的区分,只留一个就行,
returFraction(x*fb.y+y*fb.x,y*fb.y);
}
Fractiooperator*(const Fraction& fb)const{
returFraction(x*fb.x,y*fb.y);
}
Fractiooperator*=(const Fraction& fb){ //当前对象要变,不能加const
x*=fb.x;
y*=fb.y;
retur*this;
}
};
//全局形式
Fractiooperator+(const Fraction& fa,const Fraction& fb){
returFraction(fa.x*fb.y+fa.y*fb.x,fa.y*fb.y);
}
clasInteger{
indata;
public:
Integer(indata=:data(data){ //后半部分才是真正的构造
}
voishow(){
cout<<data<<endl;
}
/*
//使用成员函数实现operator+
Integeoperator+(const Integer& i)const{
// returInteger(data+i.data); //匿名对象
returdata+i.data; //单参构造
}
*/
stativoid showData(Integer* mythis){ //static函数使用普通变量要this
cout<<mythis->data<<endl;
}
private:
//声明友元
frienconst Integer operator+(const Integer& ia,const Integer& ib);
};
//使用全局函数实现operator+
consInteger operator+(const Integer& ia,const Integer& ib){
//正常情况下权限有问题,可以定义一个getData()函数或用友元解决
//开头的const是为了保证返回的临时结果不可以被覆盖
returInteger(ia.data+ib.data);
} cout是ostream& 流类型不能复制,必须用引用类型,也不能const修饰,cin同理,编译器会先去ostream类型(L对象)中找一个成员函数operator<<(const Integer&),如果找不到就去全局找一个全局函数operator<<(ostream& ps,const Interger& i)
#include<iostream>
usinnamespace std;
clasInteger{
indata;
public:
Integer(indata=:data(data){ //后半部分的初始化列表的部分才是真正的构造
}
frienostream& operator<<(ostream& os,const Integer& i);
frienistream& operator>>(istream& is,Integer& i);
//成员形式的operator==
boooperator==(const Integer& i){
returdata==i.data; //返回指针的话this==&i(极少用)
}
};
//全局形式的输出运算符重载
ostreamoperator<<(ostream& os,const Integer& i){
returos<<i.data;
}
//全局形式的输入运算符重载
istreamoperator>>(istream& is,Integer& i){
returis>>i.data;
}
inmain(){
Integeia(,ib(0);
if(ia==ib){
cin>>ia;
cout<<ia<<endl;
}
retur
} 二元运算符L#R的重载中编译器会先去L对象对应的类型中找一个重载函数叫operator#(R),没有就去全局函数中找一个全局函数叫operator#(L,R),最后综合选择最优调用
先去O对象对应的类型找一个成员函数叫operator#(), 如果找不到就去全局找一个全局函数operator#(O),#默认操作符号在前,操作数在后
clasInteger{
indata;
public:
Integer(indata=:data(data){ //后半部分才是真正的构造
}
frienostream& operator<<(ostream& os,const Integer& i);
frienistream& operator>>(istream& is,Integer& i);
boooperator!(){
retur!data;
}
Integeoperator-(){
retur-data;
}
Integeroperator--(){ //前--
data--;
retur*this;
}
consInteger operator--(int){ //后--
/*
Integetmp=*this;
data--;
returtmp;
*/
returdata--; //返回的是变化之前的结果
}
Integeroperator++(){ //前++
data++;
retur*this;
}
consInteger operator++(int){ //后++
returdata++;
}
};
//全局形式的输出运算符重载
ostreamoperator<<(ostream& os,const Integer& i){
returos<<i.data;
}
//全局形式的输入运算符重载
istreamoperator>>(istream& is,Integer& i){
returis>>i.data;
}
inmain(){
Integeia(,ib();
cout<<!ia<<endl;
cout<<!ib<<endl;
cout<<-ia<<endl;
cout<<-ia<<endl; //注意是两个-,不是--
cout<<-(-ia)<<endl;
cout<<--ia<<endl;
cout<<ia--<<endl;
cout<<ia<<endl;
cout<<++ia<<endl;
cout<<ia++<<endl;
cout<<ia<<endl;
cout<<-ib<<endl;
} clasA{
inx;
iny;
public:
A(){cout<<"A()"<<endl;}
~A(){cout<<"~A()"<<endl;}
};
stativoid* operator new(size_t size){ //new运算符全局的成员的都一个样
cout<<"size="<<size<<endl;
returmalloc(size);
}
stativoid operator delete(void* ptr){
cout<<"ptr="<<ptr<<endl;
}
inmain(){
Apa=new A();
deletpa;
retur
}
strin对象的使用:
inmain(){
strinstra("hello");
strinstrb="hello";
strb="world";
if(stra==strb)
cout<<"stra==strb"<<endl;
else
cout<<"stra!=strb"<<endl;
cout<<strb<<endl;
cout<<(strb.append(test"))<<endl;
cout<<(stra+=test")<<endl;
cout<<(stra=stra+strb)<<endl;
cout<<stra.size()<<endl;
cout<<stra[4]<<endl;
cout<<stra.at(4)<<endl;
//把C++ string 变成const char*
const char* mystr=stra.c_str();
cout<<mystr<<endl;
cout<<strlen(mystr)<<endl;
} #include<iostream>
using namespace std;
class Product{
//产品数量
int pcount;
//产品单价
double price;
public:
Product(int pcount=0,double price=0.0):pcount(pcount),price(price){}
//重载()运算符
double operator()(int c,double p){
return c*p;
}
double operator()(int c,double p,double pct){
return c*p*pct;
}
//重载()运算符,把当前对象类型变成int
//int operator() (){ //Wrong!
operator int(){ //
return pcount;
}
//把当前对象类型转换成double
operator double(){
return price;
}
};
int main(){
Product iphone;
double sumprice=iphone(9,.6); //对象已经创建了,这里的()可不是初始化
cout<<sumprice<<endl;
cout<<iphone(9,.6,0.8)<<endl;
Product iphone6s(99,.4);
int c=(int)iphone6s;
cout<<c<<endl;
double p=(double)iphone6s;
cout<<p<<endl;
return 0;
} #include<iostream>
using namespace std;
class Array{
//数组容量
int len;
//元素的个数
int size;
//真正存储数据的指针
int* data;
public:
//构造
expliciArray(int len=:len(len),size(0){
//size一定要初始化为否则容易越界
//申请堆内存
data=neint[len];
}
//析构
~Array(){
//释放堆内存
delete[data;
}
//拷贝构造
Array(consArray& arr){
//浅拷贝
len=arr.len;
size=arr.size;
//深拷贝,重新申请堆内存
data=neint[len];
//复制数据
for(ini=i<size;i++)
data[i]=arr.data[i];
}
//添加数据
voipush_back(int d){
if(size>=len)
expand();
data[size++]=d;
}
//扩容
voiexpand(){
len=len+1;
//记录原来的内存
in*tmp=data;
//重新申请堆内存
data=neint[len];
//复制数据
for(ini=i<size;i++)
data[i]=tmp[i];
//释放原来的内存
delete[tmp;
}
//显示数据
//其实是全局函数写在了类内,输入输出重载不能在类内
friend ostream& operator<<(ostream& os,const Array& arr){
cout<<'[';
for(ini=i<arr.size;i++)
cout<<arr.data[i]<<' ';
cout<<"]";
}
//赋值运算符重载
Arrayoperator=(const Array& arr){
//防止自赋值
if(this!=&arr){
len=arr.len;
size=arr.size;
//释放原来的内存,防止原来的空间不够大
delete[data;
//重新申请内存
data=neint[len];
//复制数据
for(ini=i<size;i++){
data[i]=arr.data[i];
}
}
retur*this;
}
//[]运算符的重载
intoperator[](const unsigned int i){//operator[]不能有默认值,因为有了默认值作为二元运算符的[]就变成了单目运算符
retur*(data+i);
}
};
voifoo(){
Arraarra(;
arra.push_back(;
arra.push_back(;
arra.push_back(;
arra.push_back(;
arra.push_back(;
Arraarrb;
arrb=arra;
cout<<arrb[<<endl;
cout<<arrb<<endl;
}
inmain(){
foo();
retur
}