C++回顾之前置++、后置++、不等号!及赋值运算符重载

[复制链接]

1234

主题

-8

回帖

216

积分

游客

积分
216
a420995601 发表于 2018-12-21 02:03:27 | 显示全部楼层 |阅读模式
  C++回顾之前置++、后置++、不等号!及赋值运算符重载
  运算符重载的主要目的是为了让类对象能像普通数据类型一样能够进行加减乘除,自加自减等操作,非常直观方便。现在来回顾C++的自加减(分前置与后置)以及不等号非运算符,赋值运算符的重载。
  1 ++重载
  (1)前置++运算符的重载方式:
  成员函数的重载: 函数类型& operator++()
  友元函数的重载:friend 函数类型& operator++(类类型& )
  (2)后置++运算符的重载方式:
  成员函数的重载:函数类型& operator++(int)
  友元函数的重载:friend 函数类型& operator++(类类型&, int)
  注意,为了区分前置++与后置++的区别,需要在参数后增加一个"int"以示区分。含有"int"的重载方式为后置++,否则为前置++。前置--与后置--类似用法。前面说过,成员函数与友元函数的重载如果同时存在时,会先调用成员函数的重载,但是在++或--时,成员函数与友元函数的重载是不能同时存在的。
  下面举一个例子:
  #ifndef _INTEGER_H_
  #define _INTEGER_H_
  class Integer
  {
  public:
  Integer(int n);
  ~Integer();
  void Display();
  Integer& operator++(); //成员方式重载前置++
  Integer& operator++(int); //成员方式重载后置++
  friend Integer& operator++(Integer& i);//友元函数重载前置++
  friend Integer& operator++(Integer& i, int);//友元函数重载后置++
  private:
  int n_;
  };
  #endif
  下面是它们的具体代码实现:
  #include "Integer.h"
  Integer::Integer(int n):n_(n){}
  Integer::~Integer(){}
  void Integer::Display() const
  {
  cout << n_ << endl;捕鱼游戏 星力捕鱼
  }
  //最好优先使用成员函数重载,
  //成员函数重载前置++
  Integer& Integer::operator++()
  {
  ++n_;
  return *this;
  }
  //成员函数重载后置++
  Integer& Integer::operator++(int)
  {
  Integer tmp(n_);
  ++n_;
  return tmp;
  }
  //友元重载前置++
  Integer& operator++(Integer& i)
  {
  ++i.n_;
  return i;
  }
  //友元重载后置++
  Integer& operator++(Integer& i, int)
  {
  Integer tmp(i.n_);
  ++i.n_;
  return tmp;
  }
  关于!及=赋值运算符的重载以String类进行说明:
  下面是String类的定义:
  #ifndef STRING_H_
  #define STRING_H_
  class String
  {
  public:
  explicit String(const char *str="");
  String(const String& other);
  ~String();
  //应用于s="abc";的情况
  String& operator=(const char *str);//重载=
  bool operator!() const; //重载!
  void Display() const;
  private:
  char* str_;
  char* AllocAndCopy(const char* str);
  };
  #endif
  下面是具体实现:
  #include
  #include
  #include "String.h"
  using namespace std;
  String::String(const char *str)
  {
  str_ = AllocAndCopy(str);
  }
  String::~String()
  {
  delete [] str_;
  }
  char* String::AllocAndCopy(const char* str)
  {
  int len = strlen(str)+1;
  char* newstr = new char[len];
  memset(newstr, 0, len);
  strcpy(newstr, str);
  return newstr;
  }
  //深拷贝,copy assign
  String& String::operator=(const String& other) //s1 = s2
  {
  if( this == &other)
  return *this;
  delete [] str_;
  str_ = AllocAndCopy(other.str_);
  return *this;
  }
  String& String::operator=(const char* str) //s1="abc"
  {
  delete [] str_;
  str_ = AllocAndCopy(str);
  return *this;
  }
  bool String::operator!() const
  {
  return (strlen(str_) != 0 )
  }
  void String::Display() const
  {
  cout << str_ << endl;
  }
  针对String类写的一个简单的用例:
  #include "String.h"
  #include
  using namespace std;
  int main()
  {
  String s1("abc");
  String s2(s1);//copy.
  String s3;//带默认参数
  s3 = s1; //调用赋值运算符
  s3.Display();
  //默认的处理方式为:将字符串构造成String类对象,再赋值至s3,如果在构造函数前加上explicit声明,则会发生编译错误。解决的方式需要重载一个参数为const char *的等号运算符即可
  s3 = "xxx"; //调用参数为const char *的赋值运算符
  String s4;
  bool notempty;
  notempty = !s4;
  cout << notempty << endl; //1
  s4 = "aaa";
  notempty = !s4;
  cout << notempty << endl; //0
  return 0;

你喜欢看
  • python如何操作Sql Server 2008

      python如何操作Sql Server 2008   最近由于公司的一个项目需要,需要使用Sql Server 2008数据库,开 ...

  • linux内核如何管理进程

      linux内核如何管理进程   “进程”有诸多的定义,在许多的教材资料上,其定义是一个程序的执行实例, ...