关于c++友元的一些记录

友元的主要功能:

在其他类中 为 class 或者 函数设置friend 前缀声明 可以使其访问其他类中的私有数据.

使用场景:

1. 当两个对象即不是继承关系 也不是组合关系 但是关系密切到需要访问私有数据时.

(1) B中所有数据A都可以进行访问.

1 class A {
2 };
3
4 class B {
5
6   friend class A;
7 };

(2) 只对部分A中的函数开放.

 1  class B;
 2
 3 class A {
 4
 5   void foo(const B& b);
 6
 7 };
 8
 9 class B {
10
11     friend void A::foo(const B& b);
12
13 };

调用顺序问题:

编译器发现  class A 中 foo(const B& b), 所以class B 要在 class A之前声明. 
  编译器发现 A::foo(xx)后先检查class A的声明, 所以class A要在class B之前声明.

造成循环依赖问题, 所以用B& 作为参数 class B前置声明一下, 可以解决此问题.

详情请见: c++ primier plus 15章节

2. 运算符重载中使用友元使参数更加清晰, 提高可读性.

 1 class C {
 2     public:
 3      explicit C(int v) : value(v) {}
 4
 5      C operator + (int v) {
 6          return C(v + this->value);
 7      }
 8      friend C operator + (const C& c, int v) {
 9          return C(c.value + v);
10      }
11     private:
12     int value;
13 };

3. <C++程序设计语言> 描述:如果希望某个运算的所有运算对象都唔唔允许隐式类型转换,实现它的函数应该作为非成员函数, 取const引用参数或者非引用参数。那些在应用时不需要基础类型的左值的运算符(+,-,|| 等),实现它们的函数常常采用这种方式。这些运算符经常需要访问其运算对象类的内部表示,因此,它们是friend函数的最常见的来源。

使用成员函数的局限是只可以调用当前对象的运算符重载. 如果使用友元可以打破此局限.

 1 class B {
 2     public:
 3         B(int v) : mvB(v) {}
 4         friend B operator + (int a, const B& b) {
 5             return B(a + b.mvB);
 6         }
 7         B operator + (int a) {
 8             return B(this->mvB + a);
 9         }
10     private:
11         int mvB;
12 };
13
14
15 B b(2);
16 b = b + 1;   // operator + (int a);
17 b = 1 + b;   // operator + (int a, const B& b);
时间: 2025-01-04 16:33:51

关于c++友元的一些记录的相关文章

c++编程规范的纲要和记录 (转)

这是一本好书, 可以让你认清自己对C++的掌握程度. 看完之后,给自己打分,我对C++了解多少? 答案是不足20分. 对于我自己是理所当然的问题, 就不提了, 记一些有启发的条目和细节: (*号表示不能完全理解,实力升级了之后回头看) 一般性问题: 1. 不要在注释中重复写代码语义,这样很容易产生不一致. 应该编写的是解释方法和原理的说明性注释. 2. 不要对每个项目每个文件进行强制的排版格式规定, 在同一个文件中风格一致即可. 3. 匈牙利记法是混用了类型不安全语言中的设施, 在面向对象语言中

论友元函数和友元类

今天闲来无事,温习了一下C++的友元函数和友元类.这里记录一下心得,加深一下自己的印象. 首先我们得了解一下什么叫友元函数,所谓友元函数首先它得是一个函数(废话).其次,这个函数必须被某个类显式的声明为自己的友元函数. 举一个例子:1 class A 2  { 3   friend void setX(A &,int);//申明setX为友元函数 4 5    public: 6      A():x(0){}//初始化x为0 7    private: 8      int x; 9   };

c++学习记录(三)

c++面向对象记录(二) 1.继承 继承是面向对象程序设计的一个重要概念.继承指依据另一个类来定义一个类,就好像子女继承父母的基因.运用继承的方法,我们就不需要重新编写数据成员.已有的类称为基类,新建的类称为派生类或者子类. (1)子类定义 定义一个子类,使用格式: \\class 子类名: 访问修饰符 基类名 (2)访问控制和继承 子类可以访问基类中的非私有成员,不可访问私有成员.子类继承了除下列情况外基类的所有方法: ·基类的构造方法.析构方法和拷贝构造函数 ·基类的重载运算符 ·基类的友元

老男孩Linux运维第41期20170917开班第四周学习重点课堂记录

第1章 必知必会文件 配置文件位置 该文件作用 /etc/sysconfig/network-scripts/ifcfg-eth0 第一块网卡的配置文件 同setup中的network /etc/resolv.conf 客户端DNS配置文件,优先级低于网卡配置文件 /etc/hosts 主要作用是定义IP地址和主机名的映射关系(域名解析),是一个映射IP地址和主机名的规定 /etc/sysconfig/network 用于配置hostname和networking /etc/fstab 开机自动

SSISDB8:查看SSISDB记录Package执行的消息

在执行Package时,SSISDB都会创建唯一的OperationID 和 ExecutionID,标识对package执行的操作和执行实例(Execution Instance),并记录operation message,统计executable的执行时间,便于developers 优化package的设计,对package进行故障排除. 一,在package发生错误时,查看失败的Executable An executable is a task or container that you

使用插件bootstrap-table实现表格记录的查询、分页、排序等处理

在业务系统开发中,对表格记录的查询.分页.排序等处理是非常常见的,在Web开发中,可以采用很多功能强大的插件来满足要求,且能极大的提高开发效率,本随笔介绍这个bootstrap-table是一款非常有名的开源表格插件,在很多项目中广泛的应用.Bootstrap-table插件提供了非常丰富的属性设置,可以实现查询.分页.排序.复选框.设置显示列.Card view视图.主从表显示.合并列.国际化处理等处理功能,而且该插件同时也提供了一些不错的扩展功能,如移动行.移动列位置等一些特殊的功能,插件可

Git 使用记录

在win7平台已经安装好了git的情况下: 1,Git 本地仓库建立与使用步骤: (2)新建立文件夹: $ mkdir learngit $ cd learngit $ pwd /Users/michael/learngit (1)引入git: 通过git init命令把这个目录变成Git可以管理的仓库: $ git init Initialized empty Git repository in /Users/michael/learngit/.git/ (3)添加文件:git add fil

前端学HTTP之日志记录

前面的话 几乎所有的服务器和代理都会记录下它们所处理的HTTP事务摘要.这么做出于一系列的原因:跟踪使用情况.安全性.计费.错误检测等等.本文将谥介绍日志记录 记录内容 大多数情况下,日志的记录出于两种原因:査找服务器或代理中存在的问题(比如,哪些请求失败了),或者是生成Web站点访问方式的统计信息.统计数据对市场营销.计费和容量规划(比如,决定是否需要增加服务器或带宽)都非常有用 可以把一个HTTP事务中所有的首部都记录下来,但对每天要处理数百万个事务的服务器和代理来说,这些数据的体积超大,很

ClientDataSet中动态添加计算字段并用计算字段显示记录的UpdateStatus

ClientDataSet中每条记录都有UpdateStatus=(usUnmodified, usModified, usInserted, usDeleted)记录该条数据是修改的,删除的,还是新增的等.有时候我们只想看修改的或新增的或删除的就可能用到这一属性.下图用计算字段显示UpdateStatus状态. ********************************************************************************************