zl程序教程

您现在的位置是:首页 >  后端

当前栏目

C++系列笔记(六)

C++笔记 系列
2023-06-13 09:11:25 时间

导读】《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

  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

文章编辑 | 谢文锐

微信编辑 | 谢文锐

微信审核 | 谢文锐