运算符重载的主要目的是为了让类对象能像普通数据类型一样能够进行加减乘除,自加自减等操作,非常直观方便。现在来回顾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 <string.h>
#include <iostream>
#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 <iostream>
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;
}