C++之单目运算符重载
2016-06-04 11:16
351 查看
这里以“-”(负号,不是减号)为例:
先用成员函数重载来实现:
运行结果如下:
可以看出没有错,这里要注意,进行负号操作,并没有改变对象值的本身,所以这里不能直接操作对象本身,需要重建一个新对象,下面多加一步操作:
运算符重载不变,对于
这么一个普通变量,系统是不允许这么操作的,左值不允许是运算,但
缺编译通过了,现在这是不可以的,那么就会说将运算符重载的函数返回值类型改成const就可以了,下面就改一下:
(-c) = t;的确是报错了,但是
这两句也同样报错了,因为把返回值类型改成const complex,那么(-c)变成了const对象,当时说const对象时说过const对象必须保证不能修改数据成员,所以只能调用const的成员函数,这里把(-(-c))转换一下:
第一个c.operator-()返回一个const complex对象,再调用operator-()自然就会出错,又因为dis同样不是const成员函是,两者都报错是必然的。那么再修改一下:
这样就只有该报错的报错,不该报错的通过喽。
然后再用友元函数重载一下:
可以看出来,友元重载有一个参数,而成员函数重载没有参数,跟双目运算符重载一样,友元重载比成员函数重载多一个参数。
还可以看出来这里友元要比成员函数重载略简单一些。而前面+=双目重载则是成员函数重载要简单一些,实际应该用友元重载还是成员函数重载还要自己多敲代码,比较一下那个方便用那个就好。
最后再举个前- -和后- -的例子:
1、前- -
运行结果是这样的:
可以看到结果是正确的。返回类型为什么是引用类型这里就不重复解释了,双目运算符重载中有说明。
同时,也可以看出,前- -是可以作为左值的。
再给出个友元重载:
运行结果同样是正确的,在这就不截图了。
2、后- -
后–不同于前- -,比如a- -,先做a = a, 再做 a = a - 1;的操作,同时重载的参数中有一个int的哑元(也就是说有类型,没有名字的参数),重载函数中,要先赋值,再做-1的操作,这里要注意三个问题:
第一个问题:做–操作的对象是谁,是对象本身,还是函数中重新定义的对象t, 当然操作的是对象本身,而并不是对象t;
第二个问题:函数应该返回的是谁,应该返回对象本身,还是对象t,首先知道b = a- -;这里b = a; 还是b = a - 1; 显然b = a; 那么就应该返回t,也就是说对象–之前的值。
第三个问题:后- -操作是不能作为左值的,那么就要返回一个const complex,这样不准改变返回的值,自然就不能当左值了。
同时还有个要说明的,像下面这样:
后–是不允许连用的,这也是通过将返回值类型改成const来限制的。而前–是可以连用的,没有const的限制。
再用友元函数重载实现如下:
单目运算符重载就说到这,还是要多联系,多敲代码才是王道。
先用成员函数重载来实现:
class Complex{ private: float _x; float _y; public: Complex(float x = 0, float y = 0):_x(x), _y(y){} void dis(){ cout << "( " << _x << "," << _y << " )" << endl; } Complex operator-(){ Complex t; t._x = -this->_x; t._y = -this->_y; return t; } }; int main() { int a = 10; cout << -a << endl; cout << -(-a) << endl; cout << "------------------" << endl; Complex c(1, 1); Complex t(2, 2); (-c).dis(); (-(-c)).dis(); return 0; }
运行结果如下:
可以看出没有错,这里要注意,进行负号操作,并没有改变对象值的本身,所以这里不能直接操作对象本身,需要重建一个新对象,下面多加一步操作:
int main() { int a = 10; cout << -a << endl; cout << -(-a) << endl; (-a) = 20; //编译报错 cout << "------------------" << endl; Complex c(1, 1); Complex t(2, 2); (-c).dis(); (-(-c)).dis(); (-c) = t; return 0; }
运算符重载不变,对于
(-a) = 20;
这么一个普通变量,系统是不允许这么操作的,左值不允许是运算,但
(-c) = t;
缺编译通过了,现在这是不可以的,那么就会说将运算符重载的函数返回值类型改成const就可以了,下面就改一下:
class Complex{
private:
float _x;
float _y;
public:
Complex(float x = 0, float y = 0):_x(x), _y(y){}
void dis(){
cout << "( " << _x << "," << _y << " )" << endl;
}
const Complex operator-(){
Complex t;
t._x = -this->_x;
t._y = -this->_y;
return t;
}
};
int main()
{
int a = 10;
cout << -a << endl;
cout << -(-a) << endl;
(-a) = 20; //编译报错
cout << "------------------" << endl;
Complex c(1, 1);
Complex t(2, 2);
(-c).dis(); //编译报错 (-(-c)).dis(); //编译报错
(-c) = t;//编译报错
return 0;
}
(-c) = t;的确是报错了,但是
(-c).dis(); //编译报错 (-(-c)).dis(); //编译报错
这两句也同样报错了,因为把返回值类型改成const complex,那么(-c)变成了const对象,当时说const对象时说过const对象必须保证不能修改数据成员,所以只能调用const的成员函数,这里把(-(-c))转换一下:
(c.operator-()).operator-();
第一个c.operator-()返回一个const complex对象,再调用operator-()自然就会出错,又因为dis同样不是const成员函是,两者都报错是必然的。那么再修改一下:
class Complex{
private:
float _x;
float _y;
public:
Complex(float x = 0, float y = 0):_x(x), _y(y){}
void dis(){
cout << "( " << _x << "," << _y << " )" << endl;
}
void dis() const{
cout << "( " << _x << "," << _y << " )" << endl;
}
const Complex operator-()const{
Complex t;
t._x = -this->_x;
t._y = -this->_y;
return t;
}
};
int main()
{
int a = 10;
cout << -a << endl;
cout << -(-a) << endl;
(-a) = 20; //编译报错
cout << "------------------" << endl;
Complex c(1, 1);
Complex t(2, 2);
(-c).dis();
(-(-c)).dis();
(-c) = t;//编译报错
return 0;
}
这样就只有该报错的报错,不该报错的通过喽。
然后再用友元函数重载一下:
class Complex{
private:
float _x;
float _y;
public:
Complex(float x = 0, float y = 0):_x(x), _y(y){}
void dis(){
cout << "( " << _x << "," << _y << " )" << endl;
}
void dis() const{
cout << "( " << _x << "," << _y << " )" << endl;
}
friend const Complex operator-(const Complex &a){
Complex t;
t._x = -a._x;
t._y = -a._y;
return t;
}
};
int main()
{
int a = 10;
cout << -a << endl;
cout << -(-a) << endl;
(-a) = 20; //编译报错
cout << "------------------" << endl;
Complex c(1, 1);
Complex t(2, 2);
(-c).dis();
(-(-c)).dis();
(-c) = t; //编译报错
return 0;
}
可以看出来,友元重载有一个参数,而成员函数重载没有参数,跟双目运算符重载一样,友元重载比成员函数重载多一个参数。
还可以看出来这里友元要比成员函数重载略简单一些。而前面+=双目重载则是成员函数重载要简单一些,实际应该用友元重载还是成员函数重载还要自己多敲代码,比较一下那个方便用那个就好。
最后再举个前- -和后- -的例子:
1、前- -
class Complex{ private: float _x; float _y; public: Complex(float x = 0, float y = 0):_x(x), _y(y){} void dis(){ cout << "( " << _x << "," << _y << " )" << endl; } Complex& operator--(){ --this->_x; --this->_y; return *this; } }; int main() { int a = 10; --a; cout << a << endl; (--a) = 20; cout << a << endl; cout << "-----------------------" << endl; Complex c(10, 10); Complex b(20, 20); (--c).dis(); (--c) = b; c.dis(); return 0; }
运行结果是这样的:
可以看到结果是正确的。返回类型为什么是引用类型这里就不重复解释了,双目运算符重载中有说明。
同时,也可以看出,前- -是可以作为左值的。
再给出个友元重载:
friend Complex& operator--(Complex &a){ --a._x; --a._y; return a; }
运行结果同样是正确的,在这就不截图了。
2、后- -
class Complex{ private: float _x; float _y; public: Complex(float x = 0, float y = 0):_x(x), _y(y){} void dis(){ cout << "( " << _x << "," << _y << " )" << endl; } void dis() const{ cout << "( " << _x << "," << _y << " )" << endl; } const Complex operator--(int){ Complex t = *this; this->_x--; this->_y--; return t; } }; int main() { int a = 10; cout << a-- << endl; cout << a << endl; (a--) = 20; //编译报错 cout << "-----------------------" << endl; Complex c(10, 10); Complex d = c--; d.dis(); c.dis(); Complex b(20, 20); (c--) = b; //编译报错 return 0; }
后–不同于前- -,比如a- -,先做a = a, 再做 a = a - 1;的操作,同时重载的参数中有一个int的哑元(也就是说有类型,没有名字的参数),重载函数中,要先赋值,再做-1的操作,这里要注意三个问题:
第一个问题:做–操作的对象是谁,是对象本身,还是函数中重新定义的对象t, 当然操作的是对象本身,而并不是对象t;
第二个问题:函数应该返回的是谁,应该返回对象本身,还是对象t,首先知道b = a- -;这里b = a; 还是b = a - 1; 显然b = a; 那么就应该返回t,也就是说对象–之前的值。
第三个问题:后- -操作是不能作为左值的,那么就要返回一个const complex,这样不准改变返回的值,自然就不能当左值了。
同时还有个要说明的,像下面这样:
a----; c----;
后–是不允许连用的,这也是通过将返回值类型改成const来限制的。而前–是可以连用的,没有const的限制。
再用友元函数重载实现如下:
friend const Complex operator--(Complex & a, int){ Complex t = a; a._x--; a._y--; return t; }
单目运算符重载就说到这,还是要多联系,多敲代码才是王道。
相关文章推荐
- C++ inline 函数
- inline在C++中做什么的?
- C++operator用法.
- C++ operator关键字(重载操作符)
- C/C++知识点汇总
- C语言数字转换为字符的问题
- C语言数组
- C语言运算符优先级 之 快速记忆
- c++ 中 const_iterator 和 const vector<>::iterator的区别
- DirectX在VS2015上编译时遇到“无法解析的外部符号 __vsnwprintf”的解决方法及原因
- 欢迎使用CSDN-markdown编辑器
- Unicode与UTF-8互转(C语言实现)
- c语言实现回调函数
- 第十五周阅读程序(6)
- 第十五周 阅读程序(5)
- Gcc在Windows下编写C语言
- 第十五周项目 阅读程序(4)
- C++判断string是不是数字
- 第十五周项目阅读程序(3)
- stackWithTemplate