个人知识库 个人知识库
首页
关于
  • C语言
  • CPlusPlus
  • Linux
  • PHP
  • Nginx
  • MySQL
  • Redis
  • Docker
  • Kubernetes
  • SRS
阅读
常用工具
  • 分类
  • 标签
  • 归档
GitHub

Agnes001

坚持是一件很伟大的事业
首页
关于
  • C语言
  • CPlusPlus
  • Linux
  • PHP
  • Nginx
  • MySQL
  • Redis
  • Docker
  • Kubernetes
  • SRS
阅读
常用工具
  • 分类
  • 标签
  • 归档
GitHub
  • C语言

  • CPlusPlus

    • 基础特性

      • 枚举
      • 字符指针
    • vs2019设置
    • C++11特性

    • 并发编程

    • 引用
    • 类和对象
    • 友元和运算符重载
      • 1 友元
        • 1.1 友元函数
        • 1.2 友元类
        • 1.3 注意事项
      • 2 运算符重载
        • 2.1 重载规则
        • 2.2 单目操作符重载
        • 2.3 输入输出运算符重载(只能通过友元函数重载)
        • 2.4 只能通过成员函数重载的运算符
    • 继承
    • 继承和多态
    • 模板
    • C++基础总结
    • 类型转换
    • 异常
    • 容器
    • 算法
    • C++程序设计
    • C++ Primer总结
    • 编程技巧
    • 标准库体系结构与内核分析
    • 设计模式
    • cmake配置C++工程
    • libcurl的使用总结
    • web开发框架--drogon
    • log4cplus使用
    • C++数据类型
    • 函数
    • 线程
    • 进程
    • 文件操作
    • 日常问题记录
    • Cpp案例程序
    • 多线程
    • 侯捷c++11新特性
    • 侯捷stl
  • Lua技术栈

  • edoyun

  • 内存管理

  • 数据结构

  • 网络编程

  • Linux

  • 池化技术

  • 操作系统

  • python

  • 编程技术
  • CPlusPlus
Agnes001
2021-12-30

友元和运算符重载

# 1 友元

# 1.1 友元函数

友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend,格式为:friend 类型 函数名(形式参数); 一个函数可以是多个类的友元函数,只需要在各个类中分别声明。

//友元函数的目的就是为了访问类的私有数据成员
//全局函数作友元函数
friend double Distance(Point &a, Point &b);	
//类的成员函数作友元函数
friend double ManagerPoint::Distance(Point &a, Point &b);	

# 1.2 友元类

友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。 当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。
定义友元类的语句格式如下:
friend class 类名;
其中:friend和class是关键字,类名必须是程序中的⼀个已定义过的类。

例如,以下语句说明类B是类A的友元类:	
class A	
{
	...	
	public:	
		friend class B;	
		...	
};
经过以上说明后,类B的所有成员函数都是类A的友元函数,能存取类A的私有成员和保护成员。

# 1.3 注意事项

  1. 因为友元不是授权类的成员,所以它不受其所在类的声明区域public private和protected的影响。通常我们选择把所有友元声明组织在一起并放在类头之后。
  2. 友元关系不能被继承。
  3. 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
  4. 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的声明。

# 2 运算符重载

运算符重载的本质是函数重载。

# 2.1 重载规则

可被重载的运算符:new, new[], delete, delete[], +, -, , /, %, ^, &, |, ~, !, =, ..., ,, ->, ->, (), [] 不能重载的运算符:.; ::; .*; ?: ;
重载方式: 友元重载和成员重载

# 2.2 单目操作符重载

重点区分前置操作还是后置操作

// 前++
friend Complex& operator++(Complex& c);	
Complex& operator++(Complex& c)		
{	
	c._x++;	
	c._y++;		
	return c;			
}	
// 后++
friend const Complex operator++(Complex &c,int);
const Complex operator++(Complex &c,int)
{	
	Complex	t(c._x,c._y);
	c._x++;
  	c._y++;
	return t;
}
// 也可以用下面的方式定义
const Complex operator++(int)
{
	Complex	t = *this;	
	_x++;
	_y++;
	return t;
}

# 2.3 输入输出运算符重载(只能通过友元函数重载)

需要通过友元来实现,避免修改c++的标准库。

friend ostream& operator<<(ostream &os,	const Complex& c);	
friend istream& operator>>(istream &is,	Complex& c);	

ostream& operator<<(ostream	&os, const Complex& c)		
{	
	os<<"("<<c._x<<","<<c._y<<")";	
	return	os;		
}	
istream& operator>>(istream&is, Complex& c)		
{	
	is>>c._x>>c._y;	
	return	is;						
}

# 2.4 只能通过成员函数重载的运算符

# 2.4.1 赋值运算符重载 (operator=)

用一个己有对象,给另外一个己有对象赋值。两个对象均己创建结束后,发 生的赋值行为。

String& String::operator=(const String& str)
{
	//1.首先判断是否赋值给自己
   	if (this == &str)
     	return *this;
	//2.删除指针之前分配的内存
    delete[] m_data;
	//3.拷贝,需要分配内存,最好通过new进行分配
    m_data = new char[strlen(str.m_data) + 1 ];
    strcpy(m_data, str.m_data);
    return *this;
}

# 2.4.2 数组下标运算符 (operator[])

设 x 是类 X 的一个对象,则表达式 x[y] 可被解释为 x.operator[](y)

int& operator[](int index) 
{
	return v[i];
}

# 2.4.3 函数调用符号 (operator())

把类对象像函数名一样使用。
仿函数(functor),就是使一个类的使用看上去象一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。

#include <iostream>
using namespace	std;	
class Sqr	
{	
public:	
	int operator()(int	i)	
	{	
		return i*i;	
	}	
	double operator()(double	d)	
	{	
		return d*d;	
	}
};	
int	main()	
{	
	Sqr	sqr;	
	int	i = sqr(4);	
	double d =	sqr(5.5);	
	cout<<i<<endl;	
	cout<<d<<endl;	
	return 0;		
}
编辑此页
#friend
类和对象
继承

← 类和对象 继承 →

Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式