运算符重载概念与原理
如果不做特殊处理,C++的 +、-、*、/ 等运算符只能用于对基本类型的常量或变量进行运算,不能用于对象之间的运算。
有时希望对象之间也能用这些运算符进行运算,使程序达到更简洁、易懂的目的。例如,复数是可以进行四则运算的,两个复数对象相加如果能直接用+运算符完成,不是很直观和简洁吗?
利用 C++ 提供的“运算符重载”机制,赋予运算符新的功能,就能解决用+将两个复数对象相加这样的问题。
运算符重载,就是对已有的运算符赋予多重含义,使同一运算符作用于不同类型的数据时产生不同的行为。运算符重载的目的是使得 C++ 中的运算符也能够用来操作对象。
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)
运算符重载注意点
1、运算重载符不可以改变语法结构。
2、运算重载符不可以改变操作数的个数。
3、运算重载符不可以改变优先级。
4、运算重载符不可以改变结合性。
可重载的运算符
双目算术运算符 | + (加),-(减),*(乘),/(除),% (取模) |
---|
单目运算符 | + (正),-(负),*(指针),&(取地址) |
关系运算符 | ==(等于),!= (不等于),< (小于),> (大于),<=(小于等于),>=(大于等于) |
逻辑运算符 | (逻辑或),&&(逻辑与),!(逻辑非) |
自增自减运算符 | ++(自增),–(自减) |
位运算符 | (按位或),& (按位与),~(按位取反),^(按位异或),,<< (左移),>>(右移) |
赋值运算符 | =, +=, -=, *=, /= , % = , &=, =, ^=, <<=, >>= |
空间申请与释放 | new, delete, new[ ] , delete[] |
其他运算符 | ()(函数调用),->(成员访问),,(逗号) [ ](下标) |
不可重载运算符
域运算符 | :: |
---|
长度运算符 | sizeof |
条件运算符 | ?: |
成员访问运算符 | . |
字符类的运算符重载
mystring.h
#include <iostream>
using namespace std;
#ifndef _MYSTRING_H
#define _MYSTRING_H
class MString
{
friend ostream &operator<<(ostream &out, MString &obj);
friend istream &operator>>(istream &in, MString &obj);
private:
char *str;
int size;
public:
MString();
MString(const char *str);
MString(const MString &obj);
~MString();
int Size(void);
char operator[](int i);
MString &operator+(const MString &obj);
MString &operator+(const char *str);
MString &operator=(const MString &obj);
MString &operator+=(const MString &obj);
bool operator==(const MString &obj);
bool operator==(const char *str);
};
#endif
mystring.cpp
#include <iostream>
#include <cstring>
#include "mystring.h"
using namespace std;
ostream &operator<<(ostream &out, MString &obj)
{
out << obj.str;
return out;
}
istream &operator>>(istream &in, MString &obj)
{
if (obj.str != NULL)
{
delete obj.str;
obj.str = NULL;
}
char buf[1024] = {0};
in.getline(buf, 1024);
obj.str = new char[strlen(buf) + 1];
strcpy(obj.str, buf);
obj.size = strlen(buf);
return in;
}
MString::MString()
{
cout << "无参构造" << endl;
this->str = NULL;
this->size = 0;
}
MString::MString(const char *str)
{
cout << "有参构造" << endl;
this->str = new char[strlen(str) + 1];
strcpy(this->str, str);
this->size = strlen(str);
}
MString::MString(const MString &obj)
{
cout << "拷贝构造" << endl;
this->str = new char[strlen(obj.str) + 1];
strcpy(this->str, obj.str);
this->size = obj.size;
}
MString::~MString()
{
cout << "析构函数" << endl;
if (this->str != NULL)
{
delete str;
this->str = NULL;
}
}
int MString::Size(void)
{
return this->size;
}
char MString::operator[](int i)
{
if (i >= 0 && i < this->size)
{
return this->str[i];
}
else
{
cout << "下标错误" << endl;
return 0;
}
}
MString &MString::operator+(const MString &obj)
{
int tmp_size = strlen(this->str) + strlen(obj.str);
char *temp = new char[tmp_size];
strcpy(temp, this->str);
strcat(temp, obj.str);
static MString s(temp);
if (strcmp(s.str, temp) != 0)
{
strcpy(s.str, temp);
}
if (temp != NULL)
{
delete temp;
temp = NULL;
}
return s;
}
MString &MString::operator+(const char *str)
{
int temp_size = strlen(this->str) + strlen(str) + 1;
char *temp = new char[temp_size];
strcpy(temp, this->str);
strcat(temp, str);
static MString s(temp);
if (strcmp(s.str, temp) != 0)
{
strcpy(s.str, temp);
}
if (temp != NULL)
{
delete temp;
temp = NULL;
}
return s;
}
bool MString::operator==(const MString &obj)
{
if (this->size == obj.size && strcmp(this->str, obj.str) == 0)
{
return true;
}
return false;
}
bool MString::operator==(const char *str)
{
if (this->size == strlen(str) && strcmp(this->str, str) == 0)
{
return true;
}
return false;
}
MString &MString::operator=(const MString &obj)
{
if (this->str != NULL)
{
delete str;
this->str = NULL;
}
this->str = new char[strlen(obj.str) + 1];
strcpy(this->str, obj.str);
this->size = strlen(obj.str);
return *this;
}
MString &MString::operator+=(const MString &obj)
{
int temp_size = strlen(this->str) + strlen(obj.str);
char *temp = new char[temp_size];
strcpy(temp, this->str);
strcat(temp, obj.str);
if (this->str != NULL)
{
delete str;
this->str = NULL;
}
this->str = new char[temp_size + 1];
strcpy(this->str, temp);
this->size = temp_size;
return *this;
}
main.cpp
#include <iostream>
#include <cstring>
#include "mystring.h"
using namespace std;
int main()
{
MString str1("hello");
MString str2("world");
cout << "str1: " << str1 << endl
<< "str2: " << str2 << endl;
cout << "str1+str2: " << endl
<< str1 + str2 << endl;
str1 += str2;
cout << "str1+=str2: " << str1 << endl;
cout << "str1+=str2的size: " << str1.Size() << endl;
cout << "str1第3个字符: " << str1[3] << endl;
str1 + "moni";
cout << "str1+moni: " << str1 << endl;
if (str1 == "welcome")
{
cout << "str1 == welcome" << endl;
}
else
{
cout << "str1 != welcome" << endl;
}
if (str1 == str2)
{
cout << "str1 == str2" << endl;
}
else
{
cout << "str1 != str2" << endl;
}
str1 = str2;
cout << "str1=str2: " << str1 << endl;
cout << "获取终端输入的字符串: ";
cin >> str1;
cout << "输出终端获取的字符串: " << str1 << endl;
}
测试结果