#include<iostream>
using namespace std;
#if 0
struct Complex //复数
{
float real;
float image;
};
Complex operator+(Complex a,Complex b)
{
Complex c;
c.real = a.real+b.real;
c.image = a.image+b.image;
return c;
}
int main()
{
//C++认为一切 一切操作符都是函数。函数是可以重载的。
//但是这里只是先粗略的认为,因为有些操作符是不可以重载的
// 那么重载这个有什么用呢,看下面的例子
// int a,b; int c=a+b;这是没有问题的。但是我们现在有个
// struct Complex这个结构体,那我们对他进行初始化
// Complex aa={1,2},bb={2,3};
// 那我们Complex cc=aa+bb;可不可以??
// 但是是不可以的。你什么时候学过结构体有加减法。
// 但是这个地方涉及到了一个问题,我想这么 做怎么办
// 可以的。我们重载这个加号就可以了。
//使用关键字 operator就行了。
int a,b;
int c=a+b;
Complex aa={1,2},bb={2,3};
Complex cc=aa+bb;
cout<<cc.real<<endl;
cout<<cc.image<<endl;
return 0;
}
#endif
#include<iostream>
using namespace std;
/*
*运算符重载规则
*1.C++不允许用户自定义新的运算符,只能对已有的C++运算符进行重载
*C++中绝大部分运算符都可以被重载,但是这个运算符是不能被重载的
*成员选择符. 成员对象选择符.* 域解析操作符:: 条件操作符?:
*前面两个运算符不能重载是为了保证访问成员的功能不能被改变,域运算符和
*sizeof运算符的运算对象是类型而不是变量或一般表达式,不具备重载的特征
*只有单目和双目能重载
*双目运算符我们重载了两个了,一个+ 一个=。
*双目就是两个操作数的意思,通常情况下,以"+"为例,通常情况下
*如果重载为成员的话需要一个参数,重载为友元的时候需要两个参数。
*请看下面这个例子
*为什么友元需要两个,而成员只需要一个呢???
*因为成员有this指针啊。
*对于单目:
*虽然我们没有重载过,但是我们应该可以想到,重载为成员的时候0个参数
*重载为友元的时候需要1个参数。
*/
#if 0
class Comple
{
public:
Comple(float x=0,float y=0)
:_x(x),_y(y)
{
}
void display()
{
cout<<"x = "<<_x<<endl;
cout<<"y = "<<_y<<endl;
}
/*
Comple operator+(Comple &a)
{
Comple b;
b._x=this->_x+a._x;
b._y=this->_y+a._y;
return b;
}
*/
friend Comple operator+(Comple &a,Comple &b);
private:
float _x;
float _y;
};
Comple operator+(Comple &a,Comple &b)
{
Comple c;
c._x=b._x+a._x;
c._y=b._y+a._y;
return c;
}
int main()
{
Comple c1(1,2),c2(2,3);
Comple c3;
c3=c1+c2;
c3.display();
return 0;
}
#endif
#if 0
/*
*重载+=
*/
class Complex
{
public:
Complex(int x=0,int y=0)
:_x(x),_y(y)
{
}
void display()
{
cout<<"(_x,_y) = ";
cout<<_x<<" "<<_y<<endl;
}
friend Complex & operator+=(Complex &a,Complex &b);
private:
int _x;
int _y;
};
//想想这里为什么不能用Complex operator+=(Complex &a,Complex &b);
//因为你在实现(a+=b)+=c的时候会出现问题,你返回的时候是存在一个
//隐式存储空间,但是那个空间一下子就消失了。你这样加a+=c是没有
//起作用的
Complex & operator+=(Complex &a,Complex &b)
{
a._x=a._x+b._x;
a._y=a._y+b._y;
return a;
}
int main()
{
Complex a(1,2),b(3,4);
a +=b;
a.display();
return 0;
}
#endif
/*
*单目运算符:只有一个操作数就叫单目运算符。
*单目运算符的使用方法是M#或者是#M(#代表单目运算符)
*也就是说这个运算符可能在前面也可能在后面。
*我们来看看下面这个例子
*operator- -代表-号
*看下面这个例子
*/
class Complex
{
public:
Complex(int x=0,int y=0)
:_x(x),_y(y)
{
}
friend Complex operator-(Complex &a);
void dis()
{
cout<<"(_x,_y) = ";
cout<<_x<<","<<_y<<endl;
}
private:
int _x;
int _y;
};
Complex operator-(Complex &a)
{
return Complex(-a._x,-a._y);
}
int main()
{
Complex a(1,2);
Complex b=-a;
b.dis();
return 0;
}
#include<iostream>
using namespace std;
/*
*堆内存操作符(new delete)
*适用于极个别情况需要定制的时候才用到,一般很少用
*void *operator new(size_t)
*void operator delete(void *)
*void *operator new[](size_t)
*void operator delete[](void *)
*
*/
class A
{
public:
A()
{
cout<<"A()"<<endl;
}
~A()
{
cout<<"~A()"<<endl;
}
int data;
};
/*
*重载为全局的就会覆盖原来的。
*
*/
//但是你看我们new A的时候没有size_t这个东西
//其实这个size_t其实就是一个unsigned int,
//他为什么写成size_t呢,就是为了实现跨平台或者将来升级用的
//new A背后还是有很多我们看不到的,new A的过程会把这个大小传进来
void *operator new(size_t size)
{
cout<<"size = "<<size<<endl;
cout<<"void *operator new(size_t)"<<endl;
void *p=malloc(size);
return p;
}
void *operator new[](size_t size)
{
cout<<"size = "<<size<<endl;
cout<<"void *operator new[]"<<endl;
void *p=malloc(size);
return p;
}
void operator delete[](void *p)
{
cout<<"void operator delete[]"<<endl;
free(p);
}
void operator delete(void *p)
{
cout<<"void operator delete"<<endl;
free(p);
}
int main()
{
/*
*new A 会有构造器的调用,new会调用前面的那个 然后拉起构造器
*delete 会拉起虚构器之后在调用delete
*但是你malloc(sizeof(A))是不会的
*/
A *p=new A[5];
delete[] p;
/*
*但是你这样之后,你new一个int也会调用你写的那个,但我想定制化
*我想生成某一个对象的时候才用定制化的。我要实现A类对象的生成
*用我自己定制的new和delete,而其他仍然用系统的。你就把那个声明为成员函数就好了。
*
*/
//malloc(sizeof(A));
//int * i=new int;
}
#include<iostream>
using namespace std;
/*
*这个文件的功能就是实现输入输出流的重载
*流输出运算符是一个单目运算符还是双目运算符。
*int main()
*{
*Complex a;
*cout<<a;
*
* }
*这里cout是一个对象,然后C又是一个对象,这是两个对象,然后两个对象
*中间加了一个操作符,这明显就是个双目的。
*从它们以前的角度来看的话,你比如说以前我们重载+号的时候,如果重载为
*成员的话,会a.operator+(b)。那同样的道理,如果我们认为这个是cout的成员的
*话,应该是cout.operator(c)。但是我们不能进去改cout.operator<<,人家是标准
*库里面的,我们哪能去改啊。所以我们把它重载成成员的路断了。那我们重载
*为友元。我们a+b还可以写成operator+(a,b)。那我们可以写成operator<<(cout,c)
*所以我们只能重载成友元。 实现如下:
*/
class Complex
{
public:
Complex(int x=0,int y=0)
:_x(x),_y(y)
{
}
/*
*你一定见过cout<<a<<b吧,所以这里的返回值你应该知道了吧。
*/
friend ostream &operator<<(ostream &a,const Complex &c);
friend istream &operator>>(istream &is,Complex &a)
{
is>>a._x;
is>>a._y;
return is;
}
private:
int _x;
int _y;
};
ostream & operator<<(ostream &os,const Complex &c)
{
os<<c._x<<endl;
os<<c._y<<endl;
return os;
}
int main()
{
Complex a(1,2);
cin>>a;
cout<<a<<endl;
return 0;
}