C++系列笔记(六)

简介: C++系列笔记(六)

  【导读】《21天学通C++》这本书通过大量精小短悍的程序详细而全面的阐述了C++的基本概念和技术,包括管理输入/输出、循环和数组、面向对象编程、模板、使用标准模板库以及创建C++应用程序等。这些内容被组织成结构合理、联系紧密的章节,每章都可在1小时内阅读完毕,都提供了示例程序清单,并辅以示例输出和代码分析,以阐述该章介绍的主题。本文是系列笔记的第五篇,欢迎各位阅读指正!            

运算符类型和运算符重载


  C++运算符从语法层面来看,除使用关键字operator外,运算符与函数几乎没有差别。return_type operator operator_symbol(……parameter list……)

  其中operator_symbol是程序员可以定义的几种运算符之一。C++运算符分为单目运算符和双目运算符。

单目运算符


  在类声明中编写单目前缀递增运算符(++),可采用如下语法:

Date&operator++ ( )
{
//operator implementation codereturn*this;
}

 而后缀递增运算符(++)的返回值不同,且有一个输入参数

Dateopeator++ (int)
{
//store a copy of the current state of the object,before incrementing dateDateCopy (*this);
//operator implementation codereturnCopy;
}

  前缀和后缀递减运算符的声明语法与递增运算符类似,只是将声明中的++替换成--

  示例代码如下:

#include<iostream>#include<string>usingnamespacestd;
classDate{
private:intDay;
intMonth;
intYear;
public:
Date(intInputDay, intInputMonth, intInputYear)
               :Day(InputDay), Month(InputMonth), Year(InputYear) {};
Date&operator++ ()
        {
++Day;
return*this;
        }
Dateoperator++ (int)
        {
DateCopy(Day, Month, Year);
++Day;
returnCopy; 
        }
Date&operator-- ()
        {
--Day;
return*this;
        }
Dateoperator-- (int)
        {
DateCopy(Day, Month, Year);
--Day;
returnCopy;
        }
voidDispalyDate()
        {
cout<<Day<<" / "<<Month<<" / "<<Year<<endl;
        }
};
intmain()
{
DateHoliday(25, 12, 2011);
cout<<"The Day Holiday is:" ;
Holiday.DispalyDate();
++Holiday;
cout<<"day after:";
Holiday.DispalyDate();
--Holiday;
cout<<"day before:";
Holiday.DispalyDate();
return0;
}

 输出为:

TheDayHolidayis:25/12/2011dayafter:26/12/2011daybefore:25/12/2011

 在上面的代码中,如果cout<<Holiday将出现编译错误,因为cout不知如何解读Holiday对象,cout能够很好地显示 const char※,因此,要让 cout能够显示Date对象,只需添加一个返回 const char的运算符:

operatorconstchar*()
{
//operator impletmentation that returns a char*}

 所以上述代码可以改为:

#include<sstream>#include<string>classDate{
operatorconstchar*()
    {
ostringstreamformattedDate;
formattedDate<<Day<<" / "<<Month<<" / "<<Year<<endl;
DateInString=formattedDate.str();
returnDateInString.c_str();
    }
};

  就可以直接输出cout<<Holiday。

解除引用运算符和成员选择运算符


  智能指针使用了引用运算符和(->)成员选择运算符,需要添加头文件#include<memory>。智能指针类std::unique_ptr实现了上述用法。

双目运算符


  对两个操作数进行操作的运算符称为双目运算符。以全局函数或静态成员函数的方式实现的双目运算符的定义如下:

return_typeoperator_type(parameter1,parameter2);

 以类成员实现的双目运算符如下:

return_type operator_type(parameter);

 以类成员的方式实现的双目运算符只接受一个参数,其原因是第二个参数通常是从类属性获得的。

双目加法与双目减法运算符


  示例代码如下:

#include<iostream>#include<string>usingnamespacestd;
classDate{
private:
intDay,Month,Year;
public:
Date(intInputDay, intInputMonth, intInputYear)
               :Day(InputDay), Month(InputMonth), Year(InputYear) {};
Dateoperator+ (intDaysToAdd)
        {
DatenewDate(Day+DaysToAdd, Month, Year);
returnnewDate;
        }
Dateoperator- (intDayToSub)
        {
returnDate(Day-DayToSub,Month,Year); 
        }
voidDispalyDate()
        {
cout<<Day<<" / "<<Month<<" / "<<Year<<endl;
        }
};
intmain()
{
DateHoliday(25, 12, 2011);
cout<<"The Day Holiday is:" ;
Holiday.DispalyDate()DatePreviousHoliday(Holiday-16);
cout<<"PreviousHoliday is:";
PreviousHoliday.DispalyDate();
DateNextHoliday(Holiday+6);
cout<<"Nextholiday on:";
NextHoliday.DispalyDate();
return0;
}

 输出为:

TheDayHolidayis:25/12/2011PreviousHolidayis:9/12/2011Nextholidayon:31/12/2011

运算符提高了类的可用性,但实现的运算符必须合理。一般运算符都是下面这种代码格式:

voidoperator+= (intDaysToAdd)
{
Day+=DaysToAdd;
}

重载等于运算符(==)和不等于运算符(!=)

booloperator== (constDate&compareTo)
{
return ((Day==compareTo.Day)&&(Year==compareTo.Year)
&&(Month==compareTo.Month));
}
booloperator!= (constDate&compareTo)
{
return!(this->operator==(compareTo));
}

重载赋值运算符


  跟复制构造函数一样,为确保进行深复制,需要提供复制赋值运算符

Classtype&operator= (constClasstype&CopySource)
{
if (this!=&CopySource)  //protection against copy into self    {
//Assignment operator impletment    }
return*this;
}

下标运算符


  下标运算符让您能够像访问数组那样访问类,其典型语法如下:

return_type&operator [] (subscript_type&subscript);

  经典代码如下:

constchar&operator [] (intIndex) const{
if(Index<GetLength())
returnBuffer[Index];
}

函数运算符operator


  operator()让对象像函数,被称为函数运算符。函数运算符用于标准模板库(STL)中,通常是 STL算法中。其用途包括决策。根据使用的操作数数量,这样的函数对象通常称为单目谓词或双目谓词。示例代码如下:

#include<iostream>#include<string>usingnamespacestd;
classCDisplay{
public:
voidoperator () (stringInput) const        {
cout<<Input<<endl;
        }
};
intmain()
{
CDisplaymDisplayFuncObject;
mDisplayFuncObject("Dispaly this string!");
return0;
}

  这个运算符也称为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

8f9d93cf1e422e58870b9099516fd5aa.png


相关文章
|
5月前
|
算法 C++
算法笔记:递归(c++实现)
算法笔记:递归(c++实现)
|
5月前
|
编译器 C++
《Effective C++ 改善程序与设计的55个具体做法》 第一章 笔记
《Effective C++ 改善程序与设计的55个具体做法》 第一章 笔记
|
3月前
|
C++ 容器
【C/C++笔记】迭代器
【C/C++笔记】迭代器
22 1
|
3月前
|
存储 安全 程序员
【C/C++笔记】迭代器范围
【C/C++笔记】迭代器范围
63 0
|
4月前
|
C++ Windows
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
在Windows上使用Visual Studio 2022进行FFmpeg和SDL2集成开发,首先安装FFmpeg至E:\msys64\usr\local\ffmpeg,然后新建C++控制台项目。在项目属性中,添加FFmpeg和SDL2的头文件及库文件目录。接着配置链接器的附加依赖项,包括多个FFmpeg及SDL2的lib文件。在代码中引入FFmpeg的`av_log`函数输出"Hello World",编译并运行,若看到"Hello World",即表示集成成功。详细步骤可参考《FFmpeg开发实战:从零基础到短视频上线》。
113 0
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
|
6月前
|
存储 C++ 容器
黑马c++ STL部分 笔记(7) list容器
黑马c++ STL部分 笔记(7) list容器
|
6月前
|
算法 C++ 容器
黑马c++ STL常用算法 笔记(5) 常用算术生成算法
黑马c++ STL常用算法 笔记(5) 常用算术生成算法
|
6月前
|
算法 C++ 容器
黑马c++ STL常用算法 笔记(4) 常用拷贝和替换算法
黑马c++ STL常用算法 笔记(4) 常用拷贝和替换算法
|
6月前
|
存储 算法 搜索推荐
黑马c++ STL常用算法 笔记(3) 排序算法
黑马c++ STL常用算法 笔记(3) 排序算法
|
6月前
|
算法 C++
黑马c++ STL常用算法 笔记(2) 查找算法
黑马c++ STL常用算法 笔记(2) 查找算法