这次我们通过来自定义数组类型重载[]、<<、>>、==、!=运算符来学习C++运算符重载相关知识。
C++的运算符重载是C++相对于其他编程语言的一大特色。
在C++里面,我们用class自定义一个类型后,为啥可以直接使用 = 赋值运算符呢?因为 C++自动为我们做了这个动作,
我们定义的类型中没有显示定义=运算符,它会自动为我们添加默认的operator=重载函数。
我们进行运算符重载是应该改变其原来的意义!比如说原来是加的含义,你给重载为减的含义那就不应该了。
进行运算符重载有2种方式。
第一种:将运算符重载放在全局函数,这种方式的函数参数,至少有一个是我们自定义类型,不然就改变运算符的本来的意义了。
第二种:将运算符重载放在自定义class类中,这种方法方便访问类中的私有成员。第一种如果要频繁的访问类中的私有成员,可以使用将其作为类的友元函数。
如果一个函数要频繁的访问类的私有成员,必须通过方法进行调用,这样会增加函数调用压栈出栈的开销,我们可以将这个函数定义为类的友元函数,这样就函数可以无私处的访问的类的私有成员了。
友元函数定义类的内部,一般是先声明后定义,和普通函数声明一样,不过在前面加一个friend 关键字。
如果在全局函数进行运算符重载,那么所有的参数都必须作为函数参数。
如果是在类中进行运算符重载,函数中自动会把运算符操作的对象作为this指针传入的函数中,所以参数会少一个。如果我们要对传送的参数进行修改,如果是的c话只能传指针,c++为了更方便我们开发,添加了引用,一般我们使用引入传递。如果不是引用传递 修改只会对参数副本进行修改不会影响原对象。
返回值应该根据这个运算符运算之后的结果来确定。打个比方比如前置运算符++,可以++++a吧,那么返回值一定可以在原来的基础上继续进行改变,这样的返回值我们一般返回引用。就好比 我们重载<<运算符 返回的是ostream的引用 这样我们就可以连续使用 << 操作符了。
代码中重载了[]、<<、>>、==、!=运算符和友元函数的使用。
#pragma once
#ifndef __MY_ARRAY_H__
#define __MY_ARRAY_H__
#include
using namespace std;
class MyArray
{
public:
MyArray();
MyArray(int len);
MyArray(const MyArray &another);
int getData(int index);
void setData(int index, int data);
int getLengh();
//重载cout<<运算符 cout<< arr1 << arr2
friend ostream& operator<<(ostream &cout,MyArray& myArray);
//重载cout>>运算符 cin >> arr1 实现对数组元素的输入
friend istream& operator >> (istream &cin, MyArray& myArray);
//重载赋值操作符
MyArray& operator=(MyArray& another);
//重载下标操作符
int& operator[](int index);
//重载==操作符
bool operator==(MyArray& another);
bool operator!=(MyArray& another);
~MyArray();
private:
int len;
int* arr;
};
#endif // !__MY_ARRAY_H__
#include
#include
#include
#include "MyArray.h"
using namespace std;
MyArray::MyArray()
{
this->len = 0;
this->arr = NULL;
}
MyArray::MyArray(int len)
{
this->len = len;
this->arr = new int[len];
memset(this->arr, 0, sizeof(int)*len);
}
MyArray::MyArray(const MyArray& another)
{
this->len = another.len;
this->arr = new int[this->len];
for (size_t i = 0; i < this->len; i++)
{
this->arr[i] = another.arr[i];
}
}
int MyArray::getData(int index)
{
return this->arr[index];
}
void MyArray::setData(int index, int data)
{
this->arr[index] = data;
}
int MyArray::getLengh()
{
return this->len;
}
ostream& operator<<(ostream &cout, MyArray& myArray)
{
cout << "[";
for (size_t i = 0; i < myArray.len-1; i++)
{
cout << myArray.arr[i] <<",";
}
cout << myArray.arr[myArray.len - 1] << "]" << endl;
return cout;
}
istream& operator >> (istream &cin, MyArray& myArray)
{
cout << "请输入" << myArray.len << "个数字:" << endl;
for (size_t i = 0; i < myArray.len; i++)
{
int d = 0;
cin >> d;
myArray.arr[i] = d;
}
return cin;
}
MyArray & MyArray::operator=(MyArray & another)
{
//1、防止自身赋值
if (this == &another)
{
return *this;
}
//2、将自身开辟的空间回收
if (this->arr != NULL)
{
delete this->arr;
this->arr = NULL;
this->len = 0;
}
//3、执行深拷贝
this->len = another.len;
this->arr = new int[another.len];
for (size_t i = 0; i < this->len; i++)
{
this->arr[i] = another.arr[i];
}
//4、返回本身
return *this;
}
int & MyArray::operator[](int index)
{
return this->arr[index];
}
bool MyArray::operator==(MyArray & another)
{
if (this == &another)
{
return true;
}
if (this->len != another.len)
{
return false;
}
for (size_t i = 0; i < another.len; i++)
{
if (another.arr[i] != this->arr[i])
{
return false;
}
}
return true;
}
bool MyArray::operator!=(MyArray & another)
{
return !(*this==another);
}
MyArray::~MyArray()
{
this->len = 0;
delete[] this->arr;
}
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include "MyArray.h"
using namespace std;
int main(int argc, char *argv[])
{
MyArray arr1(10);
cout << arr1 << arr1;
cin >> arr1;
cout<<"arr1:" << arr1;
MyArray arr2 = arr1;
cout <<"MyArray arr2 = arr1\narr2:"<< arr2;
cout << "arr2 == arr1:" << boolalpha << (arr2 == arr1) << endl;
cout << "arr2 != arr1:" << boolalpha << (arr2 != arr1) << endl;
arr2[9] = 666;
cout << "arr2[9] = 666\narr2:" << arr2;
cout << "arr2 == arr1:" << boolalpha << (arr2 == arr1)<