|
//原文链接: http://blog.csdn.net/xiegenwendada/article/details/8477209 #include<stdio.h> #include <stdlib.h> /*///////////////////////////// 操作符重载 //////////////////////////////////////////// - - 操作符重载必须是,参数类型或个数不同,还有是否为const,但不以返回值的类型左判断。 - - ------------------------------------------------------------------------------------ - | 不能重载的操作符号 | 可以重载的操作符 | - ------------------------------------------------------------------------------------ - | . .* :: ?: new delete sizeof | new new[] delete delete[] + - * / % ^ | - | typeid static_cast dynamic_cast | & | ~ ! = < > += -= *= /= %= ^= &= |= | - | const_cast reintERPret_cast | << >> >>= <<= == != <= >= && || ++ -- | - | | ->* -> () [] | - ------------------------------------------------------------------------------------- - - - ------------------------------------------------------------------------------------ - | 类成员操作符重载 | 友员函数操作符重载 | - ------------------------------------------------------------------------------------ - | 左右操作数都是该类对象 | 左操作数为其它类型 | - | 必须为类成员操作符: | | - | 赋值(=),下标([]),调用(()) | | - | 和成员访问箭头(->) | | - ------------------------------------------------------------------------------------- - //////////////////////////////// 操作符重载 ////////////////////////////////////////////*/// 简单的重载 class CBaseOperator { public: int nData; //测试的变量 public: CBaseOperator( int nData = 0):nData(nData) { nData++; --nData; } CBaseOperator( const CBaseOperator& cBO) { nData = cBO.nData; } //重载=操作符,一般=操作符和拷贝构造函数是成对出现的。 const CBaseOperator& operator=( const CBaseOperator& cBO) { nData = cBO.nData; return * this; } public: //重载+操作符,简单的二元操作符重载是最常见也是比较简单的。基本思路都是这样,注意如果 //操作符出现在左边,则只能用友员了。这里了有几个返回类型是CBaseOperator,return //语句中却是两个int相加,这种情况是可以通过的,编译器会自动构建一个相应的对象返回, //前提是你的构造函数要有相应的参数,这里是int作为参数 int operator+( int nAdd) const { return nData + nAdd; } int operator+( int nAdd) { return nData + nAdd; } friend int operator+( int nAdd, const CBaseOperator& cAdd) { return nAdd + cAdd.nData; } CBaseOperator operator+( const CBaseOperator& cAdd) const { return nData + cAdd.nData; } //重载减法什么的也是一样。就不写了。哈哈
//比较操作符重载==,!=,>, >=, <, <=总结:这里都是配套的操作一般来说如果写一个 //都会重载其他几个,特别是==,!=。当然也有例外。哈哈。。 bool operator==( const CBaseOperator& cEqual) const { return nData == cEqual.nData; } bool operator == ( int nEqual) const { return nData == nEqual; } friend bool operator ==( int nEqual, const CBaseOperator& cEqual) { return cEqual.nData == nEqual; } bool operator!=( const CBaseOperator& cEqual) const { return nData != cEqual.nData; } //其他的也就不写了,基本一样。哈哈
//重载++,--操作符,因为++,--有两种方式,一种是前增量(++XXX先改变自己,返回), //一种是后增量(改变自己,返回改变前的状态) //因为重载是判断参数的,为了能区别前增量和后增量,C++的设计者做了这样的考虑。 //就是重载后增量的时候在参数列表中加一个int类型参数,这样就避免的重载的重复了。 //在调用上,如果都重载,那么用int参数的是后增量++,没有参数的是前增量++, //(注:我在这里说的是成员函数,当然友员的重载参数个数要多一个,以后的我可别说我无知啊。) //如果都重载,那么前增量和后增量都会调用相应的函数,如果只重载了后增量,那么前增量会失败 //如果只重载了前增量,就会无论是前增量和后增量都会调用这个函数。所以一般他们也是成对 //出现的,除非你懒,只写前增量,可惜如果人家要调用后增量呢?结果会错的哦。哈哈。
//重载后增量.
CBaseOperator operator++( int) { CBaseOperator cTemp = * this; ++nData; return cTemp; } //重载前增量
CBaseOperator& operator++() { ++nData; return * this; } //重载--操作符是一样的,也不写了。
//重载[],()等操作符号,同样[]的参数个数是确定的。 //我之说以把他们写一起,是因为我错误的以为[]的参数个数是可以自己定义。错了错了。 //知错能改是好的,对了,()的参数个数是可以自己定义的。这个就给我们很大的发挥空间了。 //都忘了[],() = 等操作符必须是成员函数,上面有写。不能用友员和静态成员函数
//重载[] int operator[]( int nIndex) const { return nIndex; } //重载() int operator()( int a) const { return a; } bool operator()( int a, int b) const { return a > b; } CBaseOperator operator()( int a, int b, int c) { return CBaseOperator(a+b+c+* this); } //重载*,->的操作符,*操作符就是相当于指针的*p;不过这里已经失去了原来的意义,他不是一个指针了。 //但如果是想通过他来得到一些东西,也是可以的,特别在迭代器中常用这种方法。->也是和*配对出现的。 //不过->操作符比较有意思,貌似和(*p).dddd真的差不多,所以返回的应该是一个结构的指针,我们这里 //就返回了本身,当然可以返回任何结构的指针的。(并不是只能返回本身)。
//重载*,这里参数个数是固定的,多写一个就成了乘法的操作了。哈哈 int operator*() const { return nData; } //重载->
CBaseOperator* operator->() { return this; } //其他的例如&& || 这样的操作符还是不重载的好。利用其原有的本性
//重载new delete,这里编译器做了一个限制,new必须返回void*类型, delete必须 //返回void类型。(上面说过函数重载是不检查返回类型的,和这里并没有冲突,他只是限定了返回 //类型,而不是只有返回类型不同的函数能重载,这个是编译器做的工作,一定上确保new能更好的工作吧) //还有就是他们的参数个数都是可以自定义的。new 和 new[] 是两个不同的操作符,所以还是要分别重载一下。 //delete 和 delete[] 也是两个不同的操作符。这里只重载了一个。 void* operator new(size_t size) { return malloc(size); } void* operator new[](size_t size) { return malloc(size); } void operator delete( void* P, unsigned int size) { size = 0; free(P); } }; int test_OverLoad() { const CBaseOperator cCo1(100); //判断+重载符 int nSum = cCo1 + 50; printf("%d\n", nSum); nSum = 50 + cCo1; printf("%d\n", nSum); //这里顺便检测一下拷贝构造函数
CBaseOperator co2(20); CBaseOperator co3 = co2 + cCo1; nSum = co3.nData; printf("%d\n", nSum); nSum = co3 + 60; printf("%d\n", nSum); //检测+,和=操作符
co3 = 10 + cCo1 + co2 + 20; nSum = co3.nData; printf("%d\n", nSum); //查看比较操作符 if (cCo1 == cCo1 && cCo1 == 100 && 100 == cCo1) { printf("True\n"); } co3 = co2; if (!(co3 != co2)) { printf("True\n"); } //增量操作符,cCo1是不能做这个操作的,因为他是常量
nSum = co2.nData; printf("%d\n", nSum); nSum = (co2++).nData; printf("%d\n", nSum); nSum = (++co2).nData; printf("%d\n", nSum); //测试[],
nSum = cCo1[45]; printf("%d\n", nSum); //测试()
nSum = cCo1(50); printf("%d\n", nSum); if (cCo1(45, 23)) { printf("True\n"); } co2 = co3(10,20,30); nSum = co2.nData; printf("%d\n", nSum); //测试*,这里co2并不是指针哦。只是重载了*的操作符
nSum = *co2; printf("%d\n", nSum); //测试->,这里也一样。
nSum = co2->nData; printf("%d\n", nSum); //测试new new[] delete, //这里没有测试输出。单步就知道了。
CBaseOperator* pCb1 = new CBaseOperator(); CBaseOperator* pCb2 = new CBaseOperator[10]; delete pCb1; delete pCb2; system("pause"); return 0; }
|