0、重载一元操作符的方法

一元运算符即只需要一个操作用的运算符,如取地址运算符(&)、复数(-)、自减(--)、自加(++)等。

运算符重载可以分为3种方式:类的非静态成员函数、类的友元函数、普通函数。

例如有 1 个操作数 a,一元运算符 ? (表示一个一元运算符),a? 或者?a 的操作会被解释为下面2种形式之一

//a? or ?a
a.operator?(); //类的非静态成员函数
operator?(a); //友元函数 和 普通函数

第一种形式是运算符被重载为类的非静态成员函数,没有参数。

这种方式要求操作数(即a)必须是一个对象,operator?是这个对象的非静态成员函数,

第二种形式是运算符被重载为类的友元函数 或 普通函数,有1个参数。

重载为 类的友元函数 和 普通函数的区别是 类的友元函数可以直接访问类的私有成员,而普通函数不可以。

1、重载++、--(前置 和 后置)

自增运算符(++)和 自减运算符(--)都有 前置 和 后置 2中情况。

C++中为了区分前置和后置规定:前置重载与普通运算符重载一致,后置重载需要在参数列表中加入一个无用的参数。

++/-- 的3种重载方式如下: 前置的情况可以返回类的引用,后置的情况只能返回临时对象。

//类的非静态成员函数
class X
{
X& operator++(){...} //前置++
X operator++(int){...} //后置++ X& operator--(){...}   //前置--  
X operator--(int){...} //后置--
}
/*-----------------------------------------------------*/
//类的友元函数
class X
{
friend X& operator++(X& ref){...} //前置++
friend X operator++(X& ref, int){...} //后置++ friend X& operator--(X& ref){...} //前置--
friend X operator--(X& ref, int){...} //后置--
}
/*-----------------------------------------------------*/
//普通函数
class X
{
...
}
X& operator++(X& ref){...} //前置++
X operator++(X& ref, int){...} //后置++ X& operator--(X& ref){...} //前置--
X operator--(X& ref, int){...} //后置--

下例中有3个Counter类 CounterA、CounterB 和CounterC,3个类都重载了前置++、-- 和后置++、--。

其中CounterA使用类的非静态成员函数方式重载,CounterB使用类的友元函数方式重载,CounterC使用普通函数方式重载。

#include <iostream>
using namespace std; class CounterA
{
public:
//默认构造函数(Default constructor)
CounterA(){cout<<"Default Constructor"<<endl;}
//带参数的构造函数(The constructor with parameters)
CounterA(int m):n(m){cout<<"Parameter Constructor"<<endl;}
//拷贝构造函数(Copy constructor)
CounterA(const CounterA& ref){n = ref.n; cout<<"Copy Constructor"<<endl;}
//析构函数(destructor)
~CounterA(){cout<<"Destructor"<<endl;} //重载运算符 ++(前置)
const CounterA& operator++(){++n; return *this;}
//重载运算符 ++(后置)
const CounterA operator++(int dump){CounterA Tmp(*this);++n; return Tmp;}
//重载运算符 --(前置)
const CounterA& operator--(){--n; return *this;}
//重载运算符 --(后置)
const CounterA operator--(int dump){CounterA Tmp(*this);--n; return Tmp;} //输出用函数
void display(void){cout<<"n = " << n << endl;}
//GetData
int GetVal(void){return n;} private:
int n;
}; class CounterB
{
public:
//默认构造函数(Default constructor)
CounterB(){cout<<"Default Constructor"<<endl;}
//带参数的构造函数(The constructor with parameters)
CounterB(int m):n(m){cout<<"Parameter Constructor"<<endl;}
//拷贝构造函数(Copy constructor)
CounterB(const CounterB& ref){n = ref.n; cout<<"Copy Constructor"<<endl;}
//析构函数(destructor)
~CounterB(){cout<<"Destructor"<<endl;} //重载运算符 ++(前置)
friend const CounterB& operator++(CounterB& ref){ref.n += ;return ref;}
//重载运算符 ++(后置)
friend const CounterB operator++(CounterB& ref, int dump){CounterB Tmp(ref);ref.n += ; return Tmp;}
//重载运算符 --(前置)
friend const CounterB& operator--(CounterB& ref){ref.n -= ;return ref;}
//重载运算符 --(后置)
friend const CounterB operator--(CounterB& ref, int dump){CounterB Tmp(ref);ref.n -= ; return Tmp;} //输出用函数
void display(void){cout<<"n = " << n << endl;}
//GetData
int GetVal(void){return n;}
//SetData
void SetVal(int val){n = val;} private:
int n;
}; class CounterC
{
public:
//默认构造函数(Default constructor)
CounterC(){cout<<"Default Constructor"<<endl;}
//带参数的构造函数(The constructor with parameters)
CounterC(int m):n(m){cout<<"Parameter Constructor"<<endl;}
//拷贝构造函数(Copy constructor)
CounterC(const CounterC& ref){n = ref.n; cout<<"Copy Constructor"<<endl;}
//析构函数(destructor)
~CounterC(){cout<<"Destructor"<<endl;} //输出用函数
void display(void){cout<<"n = " << n << endl;}
//GetData
int GetVal(void){return n;}
//SetData
void SetVal(int val){n = val;} private:
int n;
};
//重载运算符 ++(前置)
const CounterC& operator++(CounterC& ref){ref.SetVal(ref.GetVal()+);return ref;}
//重载运算符 ++(后置)
const CounterC operator++(CounterC& ref, int dump){CounterC Tmp(ref);ref.SetVal(ref.GetVal()+); return Tmp;}
//重载运算符 --(前置)
const CounterC& operator--(CounterC& ref){ref.SetVal(ref.GetVal()-);return ref;}
//重载运算符 --(后置)
const CounterC operator--(CounterC& ref, int dump){CounterC Tmp(ref);ref.SetVal(ref.GetVal()-); return Tmp;} int main(void)
{
CounterA cp1();cp1.display();
++cp1;cp1.display();
--cp1;cp1.display();
CounterA cp2(cp1++);cp2.display();
CounterA cp3(cp1--);cp3.display(); CounterB cp4();cp4.display();
++cp4;cp4.display();
--cp4;cp4.display();
CounterB cp5(cp4++);cp5.display();
CounterB cp6(cp4--);cp6.display(); CounterC cp7();cp7.display();
++cp7;cp7.display();
--cp7;cp7.display();
CounterC cp8(cp7++);cp8.display();
CounterC cp9(cp7--);cp9.display(); return ;
}

2、重载负号(-)

下例中有3个Complex类 ComplexA、ComplexB 和ComplexC,3个类都重载了负号。

其中ComplexA使用类的非静态成员函数方式重载,ComplexB使用类的友元函数方式重载,ComplexC使用普通函数方式重载。

#include <iostream>
using namespace std; class ComplexA
{
public:
//constructor
ComplexA(double re, double im):real(re),image(im){}
//Operator Overload : -
ComplexA operator-(){return ComplexA(-real, -image);}
//display
void display(void){if (image>)cout<<real<<"+"<<image<<endl;else cout<<real<<image<<endl;} private:
double real;
double image;
}; class ComplexB
{
public:
//constructor
ComplexB(double re, double im):real(re),image(im){}
//Operator Overload : -
friend ComplexB operator-(ComplexB& ref){return ComplexB(-ref.real, -ref.image);}
//display
void display(void){if (image>)cout<<real<<"+"<<image<<endl;else cout<<real<<image<<endl;}
private:
double real;
double image;
}; class ComplexC
{
public:
//constructor
ComplexC(double re, double im):real(re),image(im){}
//GetData
double GetReal(void){return real;}
double GetImage(void){return image;}
//display
void display(void){if (image>)cout<<real<<"+"<<image<<endl;else cout<<real<<image<<endl;} private:
double real;
double image;
}; //Operator Overload : -
ComplexC operator-(ComplexC& ref){return ComplexC(-ref.GetReal(), -ref.GetImage());} int main(void)
{
ComplexA a1(,);a1.display();
ComplexA a2(-a1);a2.display(); ComplexB b1(,);b1.display();
ComplexB b2(-b1);b2.display(); ComplexC c1(,);c1.display();
ComplexC c2(-c1);c2.display(); return ;
}

C++运算符重载——重载一元运算符的更多相关文章

  1. C++ 重载运算符和重载函数

    C++ 重载运算符和重载函数 C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是 ...

  2. C++解析七-重载运算符和重载函数

    重载运算符和重载函数C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载.重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列 ...

  3. C++ 自增、自减运算符的重载和性能分析

    01 ++.--运算符重载函数的格式 自增运算符和自减运算符是有前置和后置之分的,如: a++ // 后置自增运算符 ++a // 前置自增运算符 b-- // 后置自减运算符 --b // 前置自减 ...

  4. C++基础之自增和自减运算符的重载

    1. 格式 1.1 分为前置和后置格式: int x = 0; int y = 0; // 后置自增运算符 x++; // 前置自增运算符 ++x; // 后置自减运算符 y--; // 前置自减运算 ...

  5. C++运算符重载——重载二元运算符

    1.重载二元操作符的方法 二元运算符又称为双目运算符,即需要2个操作数的运算符,例如 + - * / 等. 运算符重载可以分为3种方式:类的非静态成员函数.类的友元函数.普通函数. 例如有 2 个操作 ...

  6. [置顶] C++基础之六:运算符的重载

    网上太多有关运算符的重载了,但是写的太过的详细,不适合新手入门,特别是那什么++和--的前增量后增量重载,一元二元运算符重载,特殊运算符,下标运算符,new和delete,甚至是指针运算符的重载,吓退 ...

  7. 【转】C++对成员访问运算符->的重载

    运算符->的重载比较特别,它只能是非静态的成员函数形式,而且没有参数. 1.如果返回值是一个原始指针,那么就将运算符的右操作数当作这个原始指针所指向类型的成员进行访问: 2.如果返回值是另一个类 ...

  8. C++题目一道: 重载`->': 您真的懂成员访问运算符的重载吗?

    原题目在这里: http://hi.baidu.com/shilyx/item/672736e14a14a90c64db003a 要求: //给出类Test的定义和实现,使程序编译通过, //并且ma ...

  9. c++的运算符的重载

    1 什么是c++运算符的重载 c++运算符的重载就是说对+.-.>.<等运算符进行重新定义,这样的话,除了基本的类型,所有的类都可以进行基本的运算了,用起来非常方便.特别是用在各种算法中. ...

随机推荐

  1. (转)android Fragments详解三:实现Fragment的界面

    为fragment添加用户界面 fragment一般作为activity的用户界面的一部分,把它自己的layout嵌入到activity的layout中.    一个 要为fragment提供layo ...

  2. Mac nginx PCRE install ngnix

    1 下载:pcre-8.12.tar.gz ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre 2 sudo tar xvfz pcre-8.1 ...

  3. typedef和自定义结构体类型

    在自定义结构体类型时会用到typedef关键字.大家都知道typedef是取别名的意思,在C语言中跟它容易混淆的有const,#define等,其区别不在本篇文章讨论之列. /*定义单链表结点类型*/ ...

  4. Teamwork——Week 4 Daily Scrum Meeting#1 2013.10.23

    一.会议议题 1)根据确立的项目题目,进一步明确PM,DEV,TEST的工作. 2)确定团队分工和预估项目时间. 3)完成项目架构NABC模型. 4)确定第一轮开发团队分工 二.会议时间 2013年1 ...

  5. LineNumberReader类

    开发人员常常会随手写一些类来读入一个简单的配置文件,或者用BufferedReader一行一行地读入特定格式的数据.这些随手写成的解析器往 往会提供基本的出错报告,但有时候它们会很难记录下出错的行号. ...

  6. 关于Web服务器域名设置相关知识积累

    1.第一个问题,如何将一个服务器映射到一个域名上呢?    在申请域名的时候,会配置服务器IP和域名的对应关系,所以如果系统中只有一个应用的情况下,应用服务器不需要做任何配置. 2.在Tomcat服务 ...

  7. NYOJ-73 比大小 AC 分类: NYOJ 2014-01-17 21:29 195人阅读 评论(0) 收藏

    典型的大数题目,这只是大数的比较,到时还有大数加减乘除,更加还有乘方,对于大数,一般用数组或者字符串,因为其他的结构类型一般都没有那么大 的范围!! 这道题目需要你仔细回想怎么比较俩个数字的大小,考虑 ...

  8. C#单链表(数据结构)

    学习单链表的源码项目:http://files.cnblogs.com/xmfdsh/CSharp%E5%8D%95%E9%93%BE%E8%A1%A8.rar 链表是用一组任意的存储单元来存储线性表 ...

  9. Python中__init__方法/__name__系统变量讲解

    __init__方法在类的一个对象被建立时,马上运行.这个方法可以用来对你的对象做一些你希望的初始化. 代码例子 test.py#!/usr/bin/python# Filename: class_i ...

  10. Grid行编辑插件

    //操作列不显示应该就是autoLoad的问题.         Ext.onReady(function () {             Ext.BLANK_IMAGE_URL = "E ...