++运算符重载
前置++运算符重载
成员函数的方式重载,原型为:
函数类型 & operator++();
友元函数的方式重载,原型为:
friend 函数类型 & operator++(类类型 &);
后置自增和后置自减的重载
成员函数的方式重载,原型为:
函数类型 & operator++(int);
友元函数的方式重载,原型为:
friend函数类型 & operator++(类类型 &,int);
#ifndef _INTEGER_H_
#define _INTEGER_H_
class Integer
{
public:
Integer(int n);
~Integer();
Integer &operator++();
//friend Integer& operator++(Integer& i);
Integer operator++(int n);
//friend Integer operator++(Integer& i, int n);
void Display() const;
private:
int n_;
};
#endif // _INTEGER_H_
#include "Integer.h"
#include <iostream>
using namespace std;
Integer::Integer(int n) : n_(n)
{
}
Integer::~Integer()
{
}
Integer &Integer::operator ++()
{
//cout<<"Integer& Integer::operator ++()"<<endl;
++n_;
return *this;
}
//Integer& operator++(Integer& i)
//{
// //cout<<"Integer& operator++(Integer& i)"<<endl;
// ++i.n_;
// return i;
//}
Integer Integer::operator++(int n)
{
//cout<<"Integer& Integer::operator ++()"<<endl;
//n_++;
Integer tmp(n_);
n_++;
return tmp;
}
//Integer operator++(Integer& i, int n)
//{
// Integer tmp(i.n_);
// i.n_++;
// return tmp;
//}
void Integer::Display() const
{
cout << n_ << endl;
}
#include "Integer.h"
#include <iostream>
using namespace std;
int main(void)
{
Integer n(100);
n.Display();
Integer n2 = ++n;
n.Display();
n2.Display();
Integer n3 = n++;
n.Display();
n3.Display();
return 0;
}
需要注意的是为了区别于前置++,后置++多了一个int 参数,但实际上是没作用的。而且此时成员函数不能与友元函数共存,因为调用++运算符时不明确。
其它运算符重载
!运算符重载
=运算符重载
[]运算符重载
+运算符重载
+=运算符重载
<<运算符重载
>>运算符重载
实现一个String.h
#ifndef _STRING_H_
#define _STRING_H_
#include <iostream>
using namespace std;
class String
{
public:
String(const char *str = "");
String(const String &other);
String &operator=(const String &other);
String &operator=(const char *str);
bool operator!() const;
char &operator[](unsigned int index);
const char &operator[](unsigned int index) const;
friend String operator+(const String &s1, const String &s2);
String &operator+=(const String &other);
friend ostream &operator<<(ostream &os, const String &str);
friend istream &operator>>(istream &is, String &str);
~String(void);
void Display() const;
int Length() const;
bool IsEmpty() const;
private:
String &Assign(const char *str);
char *AllocAndCpy(const char *str);
char *str_;
};
#endif // _STRING_H_
#include "String.h"
String::String(const char *str)
{
str_ = AllocAndCpy(str);
}
String::String(const String &other)
{
str_ = AllocAndCpy(other.str_);
}
String &String::operator=(const String &other)
{
if (this == &other)
return *this;
return Assign(other.str_);
}
String &String::operator=(const char *str)
{
return Assign(str);
}
String &String::Assign(const char *str)
{
delete[] str_;
str_ = AllocAndCpy(str);
return *this;
}
bool String::operator!() const
{
return strlen(str_) != 0;
}
char &String::operator[](unsigned int index)
{
//return str_[index];
//non const 版本调用 const版本
return const_cast<char &>(static_cast<const String &>(*this)[index]);
}
const char &String::operator[](unsigned int index) const
{
return str_[index];
}
String::~String()
{
delete[] str_;
}
char *String::AllocAndCpy(const char *str)
{
int len = strlen(str) + 1;
char *newstr = new char[len];
memset(newstr, 0, len);
strcpy(newstr, str);
return newstr;
}
void String::Display() const
{
cout << str_ << endl;
}
int String::Length() const
{
return strlen(str_);
}
bool String::IsEmpty() const
{
return Length() == 0;
}
String operator+(const String &s1, const String &s2)
{
//int len = strlen(s1.str_) + strlen(s2.str_) + 1;
//char* newstr = new char[len];
//memset(newstr, 0, len);
//strcpy(newstr, s1.str_);
//strcat(newstr, s2.str_);
//
//String tmp(newstr);
//delete newstr;
String str = s1;
str += s2;
return str;
}
String &String::operator+=(const String &other)
{
int len = strlen(str_) + strlen(other.str_) + 1;
char *newstr = new char[len];
memset(newstr, 0, len);
strcpy(newstr, str_);
strcat(newstr, other.str_);
delete[] str_;
str_ = newstr;
return *this;
}
ostream &operator<<(ostream &os, const String &str)
{
os << str.str_;
return os;
}
istream &operator>>(istream &is, String &str)
{
char tmp[1024];
cin >> tmp;
str = tmp;
return is;
}
#include "String.h"
#include <iostream>
using namespace std;
int main(void)
{
String s1("abcdefg");
char ch = s1[2];
cout << ch << endl;
s1[2] = 'A';
s1.Display();
const String s2("xyzabc");
ch = s2[2];
//s2[2] = 'M'; Error
s2.Display();
String s3 = "xxx";
String s4 = "yyy";
String s5 = s3 + s4;
s5.Display();
String s6 = "aaa" + s3 + "sdfadfa" + "xxxx";
s6.Display();
s3 += s4;
s3.Display();
cout << s3 << endl;
String s7;
cin >> s7;
cout << s7 << endl;
if (!s7.IsEmpty())
cout<<s7.Length()<<endl;
return 0;
}
C++的I/O流库的一个重要特性就是能够支持新的数据类型的输出和输入。
用户可以通过对插入符(<<)和提取符(>>)进行重载来支持新的数据类型。
流运算符的重载只能使用友元函数进行重载
问题:为什么一定要使用友元函数进行重载?
friend istream& operator>>(istream&, 类类型&);
friend ostream& operator<<(ostream&, const 类类型&);
只能将流类运算符重载为友元函数,因为第一个参数是流类对象引用,不是String 类。