C++学习day3之运算符重载

#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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值