友元关系是单向、独立的,不具备传递性。友元使得非成员函数可以访问类的私有成员,可以定义在类的任何位置。
以下是利用友元函数或成员函数重载二元运算符+
、一元运算符++/--
和操作符<<
Test.h
//Test.h
#pragma once
#include <iostream>
using namespace std;
class Test
{
public:
Test();
Test(int a, int b);
~Test();
Test& operator--();//前置--
Test& operator--(int);//后置--
private:
int m_a;
int m_b;
friend Test operator+(Test& t1, Test& t2);
friend Test& operator++(Test& t);//前置++
friend Test& operator++(Test& t, int);//后置++
//friend void operator<<(ostream& out, Test& t);//只能使用友元函数
friend ostream& operator<<(ostream& out, Test& t);//只能使用友元函数
};
Test::Test()
{
m_a = m_b = 0;
}
Test::Test(int a, int b)
{
m_a = a;
m_b = b;
}
Test::~Test()
{
}
Test operator+(Test& t1, Test& t2)
{
Test tmp;
tmp.m_a = t1.m_a + t2.m_a;
tmp.m_b = t1.m_b + t2.m_b;
return tmp;
}
//重载前置++
Test& operator++(Test& t)
{
t.m_a++;
t.m_b++;
return t;
}
//后置++
Test& operator++(Test& t, int)
{
Test tmp = t;
t.m_a++;
t.m_b++;
return tmp;
}
ostream& operator<<(ostream& out, Test& t)
{
out << t.m_a << " + " << t.m_b << "i" << endl;
return out;
}
//前置--
Test& Test::operator--()
{
this->m_a--;
this->m_b--;
return *this;
}
//后置--
Test& Test::operator--(int)
{
Test tmp = *this;
this->m_a--;
this->m_b--;
return tmp;
}
main.cpp
#include <iostream>
#include "Test.h"
using namespace std;
int main()
{
//自行调用,没想到吧!!!
//有不懂的地方可以在评论区交流发言,我看到会及时回复的
return 0;
}
=
运算符重载,=
不能被当作友元函数重载
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Equal
{
public:
Equal(const char* p);
Equal(const Equal& p);
~Equal();
Equal& operator=(Equal& obj);
private:
char* m_p;
int m_len;
};
Equal::Equal(const char* p)
{
m_len = strlen(p);
m_p = new char[m_len + 1];
strcpy(m_p, p);
}
Equal::Equal(const Equal& p)
{
m_len = p.m_len;
m_p = new char[m_len + 1];
strcpy(m_p, p.m_p);
}
Equal::~Equal()
{
if (m_p != NULL)
{
delete m_p;
m_p = NULL;
m_len = 0;
}
}
//先释放旧内存,再返回一个引用(以支持链式编程)
Equal& Equal::operator=(Equal& obj)
{
//先释放旧内存
if (this->m_p != NULL)
{
delete[] m_p;
m_len = 0;
}
//根据obj分配内存大小
m_len = obj.m_len;
m_p = new char[m_len + 1];
strcpy(m_p, obj.m_p);
return *this;
}
int main()
{
Equal obj1("callofduty");
Equal obj2("abc");
//运算符重载前,编译器执行浅拷贝,由于二次析构obj1的内存而报错
obj2 = obj1;//重载运算符后实现深拷贝
return 0;
}
举个栗子
重载数组类
Array.h
//Array.h
#pragma once
#include <iostream>
using namespace std;
class Array
{
public:
Array();
Array(int len);
Array(const Array& p);
Array& operator=(const Array& arr);
int& operator[](int index)const;
bool operator==(const Array& arr);
bool operator!=(const Array& arr);
int getLen();
void setData(int index, int data);
int getData(int index);
~Array();
private:
int m_len;
int* m_p;
friend istream& operator>>(istream& in, Array& arr);
friend ostream& operator<<(ostream& out, Array& arr);
};
Array.cpp
//Array.cpp
#include "Array.h"
istream& operator>>(istream& in, Array& arr)
{
cout << "请输入" << arr.m_len << "个整型数:" << endl;
for (int i = 0; i < arr.m_len; i++)
{
in >> arr[i];
}
return in;
}
ostream& operator<<(ostream& out, Array& arr)
{
for (int i = 0; i < arr.m_len; i++)
{
out << arr[i] << " ";
}
out << endl;
return out;
}
Array::Array()
{
this->m_p = NULL;
this->m_len = 0;
}
Array::Array(int len)
{
m_len = len;
this->m_p = new int[this->m_len];
}
Array::Array(const Array& p)
{
m_len = p.m_len;
m_p = new int[m_len + 1];
for (int i = 0; i < m_len; i++)
{
m_p[i] = p.m_p[i];
}
}
Array& Array::operator=(const Array& arr)
{
if (this->m_p != NULL)
{
delete[] m_p;
m_p = NULL;
}
this->m_len = arr.m_len;
this->m_p = new int[m_len + 1];
for (int i = 0; i < m_len; i++)
{
m_p[i] = arr.m_p[i];
}
return *this;
}
int& Array::operator[](int index)const
{
return this->m_p[index];
}
bool Array::operator==(const Array& arr)
{
if (this->m_len != arr.m_len)
return false;
else
{
for (int i = 0; i < m_len; i++)
{
if (m_p[i] != arr.m_p[i])
return false;
}
return true;
}
}
bool Array::operator!=(const Array& arr)
{
return !(*this == arr);
}
int Array::getLen()
{
return this->m_len;
}
void Array::setData(int index, int data)
{
m_p[index] = data;
}
int Array::getData(int index)
{
return m_p[index];
}
Array::~Array()
{
if (m_p != NULL)
{
delete[] m_p;
m_p = NULL;
m_len = 0;
}
}
arrayMain.cpp
//arrayMain.cpp
#include "Array.h"
#include <iostream>
using namespace std;
int main()
{
Array arr(10);
cin >> arr;
for (int i = 0; i < arr.getLen(); i++)
{
arr[i] += i;
}
cout << arr;
return 0;
}