【导读】《21天学通C++》这本书通过大量精小短悍的程序详细而全面的阐述了C++的基本概念和技术,包括管理输入/输出、循环和数组、面向对象编程、模板、使用标准模板库以及创建C++应用程序等。这些内容被组织成结构合理、联系紧密的章节,每章都可在1小时内阅读完毕,都提供了示例程序清单,并辅以示例输出和代码分析,以阐述该章介绍的主题。本文是系列笔记的第五篇,欢迎各位阅读指正!
C++运算符从语法层面来看,除使用关键字operator外,运算符与函数几乎没有差别。return_type operator operator_symbol(……parameter list……)
其中operator_symbol是程序员可以定义的几种运算符之一。C++运算符分为单目运算符和双目运算符。
在类声明中编写单目前缀递增运算符(++),可采用如下语法:
Date& operator ++ ( )
{
//operator implementation code
return *this;
}
而后缀递增运算符(++
)的返回值不同,且有一个输入参数
Date opeator ++ (int)
{
//store a copy of the current state of the object,before incrementing date
Date Copy (*this);
//operator implementation code
return Copy;
}
前缀和后缀递减运算符的声明语法与递增运算符类似,只是将声明中的++
替换成--
。
示例代码如下:
#include<iostream>
#include<string>
using namespace std;
class Date
{
private:
int Day;
int Month;
int Year;
public:
Date(int InputDay, int InputMonth, int InputYear)
:Day(InputDay), Month(InputMonth), Year(InputYear) {};
Date& operator ++ ()
{
++Day;
return *this;
}
Date operator ++ (int)
{
Date Copy(Day, Month, Year);
++Day;
return Copy;
}
Date& operator -- ()
{
--Day;
return *this;
}
Date operator -- (int)
{
Date Copy(Day, Month, Year);
--Day;
return Copy;
}
void DispalyDate()
{
cout << Day << " / " << Month << " / " << Year << endl;
}
};
int main()
{
Date Holiday(25, 12, 2011);
cout << "The Day Holiday is:" ;
Holiday.DispalyDate();
++Holiday;
cout << "day after:";
Holiday.DispalyDate();
--Holiday;
cout << "day before:";
Holiday.DispalyDate();
return 0;
}
输出为:
The Day Holiday is:25 / 12 / 2011
day after:26 / 12 / 2011
day before:25 / 12 / 2011
在上面的代码中,如果cout<<Holiday将出现编译错误,因为cout不知如何解读Holiday对象,cout能够很好地显示 const char※,因此,要让 cout能够显示Date对象,只需添加一个返回 const char的运算符:
operator const char*()
{
//operator impletmentation that returns a char*
}
所以上述代码可以改为:
#include<sstream>
#include<string>
class Date
{
operator const char*()
{
ostringstream formattedDate;
formattedDate<<Day<<" / "<<Month<<" / "<<Year<<endl;
DateInString=formattedDate.str();
return DateInString.c_str();
}
};
就可以直接输出cout<<Holiday。
智能指针使用了引用运算符和(->)成员选择运算符,需要添加头文件#include<memory>
。智能指针类std::unique_ptr
实现了上述用法。
对两个操作数进行操作的运算符称为双目运算符。以全局函数或静态成员函数的方式实现的双目运算符的定义如下:
return_type operator_type(parameter1,parameter2);
以类成员实现的双目运算符如下:
return_type operator_type(parameter);
以类成员的方式实现的双目运算符只接受一个参数,其原因是第二个参数通常是从类属性获得的。
示例代码如下:
#include<iostream>
#include<string>
using namespace std;
class Date
{
private:
int Day,Month,Year;
public:
Date(int InputDay, int InputMonth, int InputYear)
:Day(InputDay), Month(InputMonth), Year(InputYear) {};
Date operator + (int DaysToAdd)
{
Date newDate(Day + DaysToAdd, Month, Year);
return newDate;
}
Date operator - (int DayToSub)
{
return Date(Day-DayToSub,Month,Year);
}
void DispalyDate()
{
cout << Day << " / " << Month << " / " << Year << endl;
}
};
int main()
{
Date Holiday(25, 12, 2011);
cout << "The Day Holiday is:" ;
Holiday.DispalyDate();
Date PreviousHoliday(Holiday - 16);
cout << "PreviousHoliday is:";
PreviousHoliday.DispalyDate();
Date NextHoliday(Holiday + 6);
cout << "Nextholiday on:";
NextHoliday.DispalyDate();
return 0;
}
输出为:
The Day Holiday is:25 / 12 / 2011
PreviousHoliday is:9 / 12 / 2011
Nextholiday on:31 / 12 / 2011
运算符提高了类的可用性,但实现的运算符必须合理。一般运算符都是下面这种代码格式:
void operator += (int DaysToAdd)
{
Day+=DaysToAdd;
}
重载等于运算符(==)和不等于运算符(!=)
bool operator == (const Date& compareTo)
{
return ((Day==compareTo.Day)&&(Year==compareTo.Year)
&&(Month==compareTo.Month));
}
bool operator != (const Date& compareTo)
{
return !(this->operator==(compareTo));
}
跟复制构造函数一样,为确保进行深复制,需要提供复制赋值运算符
Classtype& operator = (const Classtype& CopySource)
{
if (this != &CopySource) //protection against copy into self
{
//Assignment operator impletment
}
return *this;
}
下标运算符让您能够像访问数组那样访问类,其典型语法如下:
return_type& operator [] (subscript_type& subscript);
经典代码如下:
const char& operator [] (int Index) const
{
if(Index<GetLength())
return Buffer[Index];
}
operator()让对象像函数,被称为函数运算符。函数运算符用于标准模板库(STL)中,通常是 STL算法中。其用途包括决策。根据使用的操作数数量,这样的函数对象通常称为单目谓词或双目谓词。示例代码如下:
#include<iostream>
#include<string>
using namespace std;
class CDisplay
{
public:
void operator () (string Input) const
{
cout << Input << endl;
}
};
int main()
{
CDisplay mDisplayFuncObject;
mDisplayFuncObject("Dispaly this string!");
return 0;
}
这个运算符也称为operator()函数,对象CDisplay也称为函数对象或functor。
移动构造函数和移动赋值运算符乃性能优化功能,属于C++11标准的一部分,旨在避免复制不必要的临时值(当前语句执行完毕后就不再存在的右值)。对于那些管理动态分配资源的类,如动态数组类或字符串类,这很有用。典型代码如下:
//移动构造函数声明
Myclass(Myclass&& MoveSource) //重要&&
{
PtrResource = MoveSource.PtrResource;
MoveSource.PtrResource = NULL;
}
//移动赋值函数
MyClass& operator= (MyClass&& MoveSource)
{
if (this != &MoveSource)
{
delete[] PtrResource;
PtrResource = MoveSource.PtrResource;
MoveSource.PtrResource; = NULL;
}
}
PS:我的c++系列全部代码还有笔记都上传到github上了,欢迎star和fork。
github链接:https://github.com/xwr96/21-Day-grasped-Cpp
文章编辑 | 谢文锐
微信编辑 | 谢文锐
微信审核 | 谢文锐