C++运算符重载

来源:互联网 发布:我的少女时代 知乎 编辑:程序博客网 时间:2024/06/03 22:42

1、先做技术推演

#include "iostream"using namespace std;//a+biclass  Complex{public:int a;int b;public:Complex(int a = 0, int b = 0){this->a = a;this->b = b;}void printCom(){cout<<a<<"+"<<b<<"i"<<endl;}};void main01(){Complex c1(1, 2), c2(3, 4);int a = 10, b = 20; a = a + b; //int 是基础类型,编译器已经为这些类型提供+操作了。//c1 = c1 + c2; //c1的类型是 Complex,这种类型,是自定义类型。 编译器根本不知道如何加,//但是c++编译器会给你提供一个机制,让你实现自定义类型加system("pause");}Complex ComAdd(Complex &c1, Complex &c2){Complex tmp;tmp.a = c1.a + c2.a;// 这里需要注意一下,如过a和b为private的时候是需要有友元函数的tmp.b = c1.b + c2.b;return tmp;}Complex operator+(Complex &c1, Complex &c2){Complex tmp;tmp.a = c1.a + c2.a;tmp.b = c1.b + c2.b;return tmp;}void main(){Complex c1(1, 2), c2(3, 4);//Complex c3 = ComAdd(c1, c2);//Complex c3 = operator+(c1, c2);Complex c3 = c1 + c2;   // 会自动调用相应函数c3.printCom();system("pause");}


2、两种重载操作符的方法 +    -   前置/后置加加     前置/后置减减重载,前置返回加加减减引用,后置返回对象

<pre name="code" class="cpp">#include "stdafx.h"#include "iostream"using namespace std;//a+biclass  Complex{private:int a;int b;//通过友元函数实现+操作friend Complex operator+(Complex &c1, Complex &c2);//全局函 前置++friend Complex& operator++(Complex &c2);//全局函 后置++ 用一个占位参数来区别前置++,这个参数没有别的用处,只是区别用friend Complex operator++(Complex &c2, int);// 全局函数 重载<<,没有方法去在cout类里面添加函数,只能通过全局函数实现friend ostream & operator<<(ostream &out, Complex &c1);public:Complex(int a = 0, int b = 0){this->a = a;this->b = b;}void printCom(){cout<<a<<"+"<<b<<"i"<<endl;}public://通过类的成员函数实现-操作Complex operator-(Complex &c2){Complex tmp;tmp.a = this->a -c2.a;tmp.b = b -c2.b;return tmp;}// 前置--Complex operator--(){Complex tmp;tmp = *this;this->a--;this->b--;return tmp;}// 前置--Complex& operator--(int){this->a--;this->b--;return *this;}};Complex operator+(Complex &c1, Complex &c2){Complex tmp;tmp.a = c1.a + c2.a;tmp.b = c1.b + c2.b;return tmp;}Complex& operator++(Complex &c2){c2.a++;c2.b++;return c2;}// 全局的后置++Complex operator++(Complex &c2, int){Complex tmp;tmp = c2;c2.a++;c2.b++;return tmp;}// 重载<<ostream & operator<<(ostream &out, Complex &c1){cout<<"";return out;}//1操作符重载,首先是通过函数实现的。void main(){Complex c1(1, 2), c2(3, 4);//Complex c3 = ComAdd(c1, c2);//Complex c3 = operator+(c1, c2);//2  +操作符有两个参数 左操作数 和 右操作数//3 Complex c3 = c1 + c2;c3.printCom();Complex c4 = c1.operator-(c2);c4.printCom();Complex c5 = c1 - c2 ;c5.printCom();//目标 通过类的成员函数,完成操作符重载//1 要承认操作符重载是一个函数,要写函数原型//2 写出函数调用语言 c1.operator-(c2)//3 完善函数原型 ++c2; c2.printCom();//全局函数原型推导//Complex& operator++(Complex &c2);--c2; //c2.operator--();c2.printCom();// 测试全局函数实现后置加加c2++;c2.printCom();// 测试成员函数实现后置--c2--;c2.printCom();// 函数返回值当左值的时候需要返回一个对象的引用cout<<c1<<"asdas";cout<<c2;system("pause");}


友元函数存在的极少数的意义之一就是重载<<这个操作符

重点:cout<<c1<<"dsad";函数参数当左值的时候需要返回一个对象的引用,因为假设如果返回一个int类型的数字10 = 2,这个是变异不过的,所以要返回一个引用来给引用赋值,可以实现链式编程,引用返回值的两种情况如上


3、重载 int& operator[] (int i);
Array& operator=(Array &a2);
bool operator==(Array &a1);
bool operator!=(Array &a1);

尤其要注意当[]和=返回值当左值的情况,如果不返回引用,赋值将会有问题,比如3 = 0;'a' = 'b';返回引用的时候可以a = 0;

如果=号重载不返回引用的情况下,会执行一次拷贝构造产生一个匿名对象,1、如果执行前拷贝可能会引起在析构的时候程序崩溃。2、可能会降低效率。

但是一定要注意,返回引用的时候一定不要返回函数中的临时变量,因为临时变量会析构掉,造成错误

头文件

#ifndef _ARRAY_H_#define _ARRAY_H_ class Array{private:    int mLength;    int* mSpace;public:    Array(int length);    Array(const Array& obj);    int length();    void setData(int index, int value);    int getData(int index);    ~Array();public:int& operator[] (int i);Array& operator=(Array &a2);bool operator==(Array &a1);bool operator!=(Array &a1);};//[]  =  ==  !=//#endif

cpp文件

#include "iostream"#include "Array.h"using namespace std;Array::Array(int length){    if( length < 0 )    {        length = 0;    }        mLength = length;    mSpace = new int[mLength];}Array::Array(const Array& obj){    mLength = obj.mLength;        mSpace = new int[mLength];        for(int i=0; i<mLength; i++)    {        mSpace[i] = obj.mSpace[i];    }}int Array::length(){    return mLength;}void Array::setData(int index, int value){    mSpace[index] = value;}int Array::getData(int index){    return mSpace[index];}Array::~Array(){    mLength = -1;    delete[] mSpace;}//操作符重载 //printf("array %d: %d\n", i, a1[i]) ;//a1[i] = 1;int&  Array::operator[] (int i){ return mSpace[i];}//Array a3(100);//a3 = a2; //执行=操作// 1)如果a3已经分配内存需要释放//2)根据a2开辟内存空间 把a2的值copy到a3中Array&  Array::operator=(Array &a2){if (this->mSpace != NULL){delete[] mSpace;mLength = 0;}this->mLength = a2.mLength;this->mSpace = new int[this->mLength];for (int i=0; i<this->mLength; i++){mSpace[i] = a2[i];}return *this;}//a2.operator==(a1);//if (a2==a1)bool Array::operator==(Array &a1){//a1和a2的长度是不是相等if (this->mLength != a1.mLength){return false;}//a1 a2的每一个数组元素是不是相等for (int i=0; i<this->mLength; i++){if (this->mSpace[i] != a1[i]){return false;}}return true;}//if (a2 != a1)bool  Array::operator!=(Array &a1){return !(*this == a1 );}
测试文件

#include "iostream"#include "Array.h"using namespace std;int main(){    Array a1(10);        for(int i=0; i<a1.length(); i++)    {        //a1.setData(i, i);  a1[i] = i+100;//a1.operator[](i) = i;//给数组的元素赋值 需要把数组元素本身给返回出来()//0 = i;    }        for(int i=0; i<a1.length(); i++)    {//printf("array %d: %d\n", i, a1.getData(i));// printf("array %d: %d\n", i, a1[i]) ;    }        Array a2 = a1;        for(int i=0; i<a2.length(); i++)    {        //printf("array %d: %d\n", i, a2.getData(i));//printf("array %d: %d\n", i, a2[i]);    }// Array a3(100);a3 = a2; //执行=操作// 1)如果a3已经分配内存需要释放//2)根据a2开辟内存空间 把a2的值copy到a3中。printf("a3:len %d", a3.length());for(int i=0; i<a3.length(); i++){printf("array %d: %d\n", i, a3[i]);}a1 = a3 = a2; //执行=操作// a1.operator=(a3.operator=(a2)); // a1.operator=(void)//a2.operator==(a1);if (a2==a1){printf("相等");}else{printf("不相等");}if (a2 != a1){printf("不相等");}else{printf("相等");}    system("pause");    return 0;}





0 0
原创粉丝点击