1. 友元函数:
作用:
- 可以在函数外部直接访问私有成员,但是友元破坏封装性
格式:
-
(类内)friend 函数类型 函数名(参数列表);
-
(类外)函数类型 函数名(参数列表){函数体};
说明:
-
友元不属于成员函数,在类外实现时不需要加上类解析(A::)
-
没有this指针,不受访问权限的控制
友元类:
-
格式:
- class 类名1{friend class 类名2;}
-
说明:
-
类名2是类名1的友元类
-
类名2可以访问类名1中的所有成员
-
友元类不常用,因为破坏封装
-
友元关系不能传递
-
2. 运算符重载:
含义: 由于类函数无法实现直接的加减运算因此对数据的运算函数需要自定义
格式:
- (类内)friend 类名 operator目标运算符(参数列表);
- 或
- (类内) 类名 operator 目标运算符(参数列表);
-
- (类外)类名 operator目标运算符(参数列表){函数体}
-
不可以进行运算符重载的操作符(5个) . :: ?: sizeof() ->
-
不能使用成员函数方式重载的运算符 << >>
-
不能通过友元函数方式重载的运算符 = () [] ->
说明:
-
运算符重载的形式可以是友元函数的形式也可以是成员函数的形式
-
成员函数有this指针,所以成员函数的运算符重载过程可以少些一个参数
-
对于不同类型的参数进行运算中,其返回值需要自己进行设计
-
一般双目运算符重载成友元 单目运算符重载成成员
-
如果想重载+ 而代码写成其它运算符的含义,代码不报错,且代码执行代码实现的含义
-
运算符重载必须是已经有的运算符,且不能改变其优先级
3. 补充:
- 运算符本质上是一种函数(在计算机中)
4. 代码实例
头文件
#pragma once
#include<iostream>
using namespace std;
class A
{
int data;
int arr[10];
public:
A(int data=0);
A(const A& other);
~A();
int getData();
void setData(int data);
friend int addData(const A&a, const A& b);
//运算符重载示例
//通过友元函数实现加法重载
friend A operator+(const A&a, const A&b);//加const防止修改 a b 的值
//通过成员函数实现减法重载
A operator-(const A& b);
//通过成员函数实现乘法重载
A operator*(const A&b);
//单目运算符重载示例 -a
A operator-();
//单目运算符重载示例 ++x(先加一然后返回值)
A& operator++();//引用可以改变之前的值
//单目运算符重载示例 x++(先返回值,然后加一)
A operator++(int);//int为了与前++区分
//重载输出运算符
friend ostream& operator<<(ostream& os, A& a);
//重载输出运算符
friend istream& operator >> (istream& is, A&a);
//重载 * 运算符
int operator*();
//重载 [] 运算符
int operator[](int index);
//重载 强制转换 运算符
operator bool();//强制转换bool类型
};
class B
{
int data;
friend class C;
};
class C
{
public:
void fun(B&b)
{
b.data = 1;
}
};
.cpp文件
#include "A.h"
A::A(int data)
{
this->data = data;
//for (int i = 0; i < 9; ++i)
//{
// arr[i] = i;
//}
}
A::A(const A& other)
{
data = other.data;
}
int A::getData()
{
return data;
}
void A::setData(int data)
{
this->data = data;
}
//友元函数
int addData(const A&a, const A& b)
{
return a.data + b.data;//直接用对象访问访问私有成员(友元的作用)
}
A operator+(const A&a, const A&b)
{
A c;
c.data = a.data + b.data;
return c;//返回临时对象c
}
A A::operator-(const A&b)
{
A c;
c = this->data - b.data;
return c;
}
A A::operator*(const A&b)
{
A c;
c = this->data * b.data;
return c;
}
A A::operator-()
{
A c;
c.data = -(this->data);
return c;
}
A& A::operator++()
{
++this->data;
return *this;
}
A A::operator++(int)
{
A c(this->data);//保存之间的值
++this->data;
return c;
}
ostream& operator<<(ostream& os, A& a)
{
os << a.data;
return os;
}
istream& operator >> (istream& is, A&a)
{
is >> a.data;
return is;
}
int A::operator*()
{
return *arr;
}
int A::operator[](int index)
{
return arr[index];
}
A::operator bool()
{
return arr[0] == 0;//结构体需要判断是判断哪个类型的值,从而写对应的值
}
A::~A()
{
}
主函数文件
#include<iostream>
#include"A.h"
using namespace std;
int main()
{
// int* arr;
A a(3), b, c,d,l;
b = a;
d.setData(a.getData() + b.getData());//非引用友元方式,使用两个对象中的数据
d.setData(addData(a, b));//使用友元的方式,直接使用两个对象中的数据
//重载加法操作实例
c = a + b;
cout << "a+b的结果是" << c.getData() << endl << endl;
//重载减法操作实例
c = a - b;
cout << "a-b的结果是" << c.getData() << endl << endl;
//重载乘法操作实例
c = a*b;
cout << "a*b的结果是" << c.getData() << endl << endl;
//重载-操作实例
c = -a;
cout << "-a的结果是" << c.getData() << endl << endl;
//重载 前++ 操作实例
c = ++a;
cout << "++a的结果是" << c.getData() << endl << endl;
//重载 后++ 操作实例
c = a++;
cout << "a++的结果是" << c.getData() << endl << endl;
//重载 输出运算符 操作实例
cout << "重载输出运算符,c的结果是"<< c << endl << endl;
//重载 输入运算符 操作实例
cout << "请输入一个值" << endl;
cin >> c;
cout << "输入的值是" << c << endl << endl;
//重载 强转bool 操作实例
cout << "强转bool的结果是" << l << endl << endl;
cin.get();
cin.get();
return 0;
}