定义类X,类Y,在类X中声明类Y的成员函数g()为类X的友元函数

常见的几种错误写法及原因:

错误写法1

class Y;
class X
{public:X(int i) :i(i) {}friend void Y::g(X& object);void  print(){cout << i;}
private:int i;
};class Y
{public:void g(X& object){object.i += 1;}
};

结果编译器显示 Y 的成员函数g()无法访问类X的私有成员i:
原因:在类X中声明Y的成员函数为友元时,此时类Y还没有定义。第一行的class Y,仅作为声明告诉编译器有这个类,而不知道这个类究竟包含了什么。所以在类X中声明成员函数g()为友元的语句无效

错误写法2

通过对刚刚写法的分析,我们很容易想到把类Y的定义放到类X前以消除这个错误,但是这样可行吗?

class X;
class Y
{public:void g(X& object){object.i += 1;}
};
class X
{public:X(int i) :i(i) {}friend void Y::g(X& object);void  print(){cout << i;}
private:int i;
};

此时编译器显示,类Y的成员函数g()仍然无法访问类X的私有成员

原因与上一个错误类似。在类Y中定义g()函数时,编译器并不知道g()作为了类X的友元,因为此时类X还没有定义,而只是在第一行作了声明。

正确写法:

class X;class Y
{public:void g(X& object);
};class X
{public:X(int i) :i(i) {}friend void Y::g(X& object);friend  class Z;friend void h(X& object);void  print(){cout << i;}
private:int i;
};void Y::g(X& object)
{object.i += 1;
}

通过把成员函数g()的定义写在类外,可以避免出现以上两种情况

总结:
编译器的编译顺序是从上至下,像这种相互使用的用法,只能先声明,最后统一实现。避免了在这一方使用那一方时出现那一方还未定义而报错的情况。

补充:
这是否说明类的友元函数只能在类外定义呢? 答案是 否定的:当定义在类Y里的友元函数不访问类x的私有成员时,这样定义没问题。

把类的成员函数声明为友元函数,但不能访问私有成员的原因和解决办法相关推荐

  1. C++友元函数 普通函数声明为友元函数

    友元函数 如果在本类以外的其他地方定义了一个函数(这个函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数),在对本类进行声明时,在类体中用friend对该函数进行声明,此函数就称为本类的&q ...

  2. R语言dplyr包filter函数 Error in filter(., ) : 找不到对象的报错原因和解决办法

    报错描述 当我们想使用dplyr包中的 filter 函数对指定的dataframe进行如下的行筛选时,R报错Error in filter(., ) : 找不到对象X.stage_id. ,提示我们 ...

  3. eclipse android 不能生成r类 appt错误,Ubuntu中Eclipse新建Android project提示缺失R文件的原因及解决办法...

    环境: 64位Ubuntu12.04进行Android开发,sun-JDK1.7,官网下载的最新ADT-Eclipse-SDK集成包.JDK配置正确.SDK已更新,版本一致 问题: 第一次启动Ecli ...

  4. 友元函数可以访问私有成员吗_C++的友元函数和友元类

    C++使用类对数据进行隐藏和封装,类的数据成员一般定义为私有成员,而将提供类与外界通讯接口的成员函数定义为公有的. C++类成员的三种访问权限: public:可以被该类中的函数.子类的函数.友元函数 ...

  5. public 函数_Chapter18:友元函数和友元类

    这一章的问题从"如何畅通无阻的访问另一个类"开始,类的属性有private.protected.public,根据继承权限有不同的访问方式.但是类之间的关系不一定是继承,有时一个类 ...

  6. c语言friend函数,C++ friend友元函数和友元类

    友元函数和友元类在实际开发中较少使用,想快速学习C++的读者可以跳过本节. 一个类中可以有 public.protected.private 三种属性的成员,通过对象可以访问 public 成员,只有 ...

  7. 基类的析构函数不能被继承。_为什么要把C++类中的析构函数声明为虚函数?

    如题,当一个类为基类的时候,通常其析构函数被声明为虚函数,这是为啥? class BaseCls { public: BaseCls() { printf("BaseCls()n" ...

  8. 为什么静态成员函数可以访问私有成员变量?(访问控制是针对类而不是针对对象)

    访问控制是针对类而不是针对对象 先看几个标准定义 A member of a class can be - private; that is, its name can be used only by ...

  9. java有没有友元函数_c++中友元函数理解与使用

    在学习c++这一块,关于友元函数和友元类,感觉还是不好理解,但是井下心来,理解,需要把我一下几点. 首先讲友元函数. (1)友元函数: 1)C++中引入友元函数,是为在该类中提供一个对外(除了他自己意 ...

最新文章

  1. Windows服务器上Mqtt服务器EMQX的安装使用
  2. 尚学堂Spring视频教程(二):Spring控制反转
  3. java togglebutton_ToggleButton和Switch使用大全
  4. 突发!王思聪名下房产、汽车、存款等被查封
  5. iphone NSTimer
  6. python教程视频哪个好-Python教学视频哪个好?老男孩Python培训
  7. 【渝粤教育】国家开放大学2018年秋季 0032-21T农业经济学 参考试题
  8. SLAM精度测评(绘制比较相机轨迹)- EVO
  9. Visitor Pattern
  10. 山东计算机软考题库,软考习题库
  11. GNU Radio Pythpn
  12. 章文嵩-构建云计算平台的实践
  13. oracle赋权语句详解,Oracle GRANT 赋权详解
  14. 【子桓说】在BAT等大公司升职的人,都明白这几点
  15. 分部积分出现积回去的情况
  16. Unity Shader Graph 制作Grid网格效果
  17. 2.1微信小程序--比较数字大小
  18. 定时任务系列(3)-Quartz动态定时任务
  19. 组员大眼瞪小眼,forEach处理异步任务遇到的坑
  20. 【L2-031 深入虎穴】天梯赛L2系列详解

热门文章

  1. 强大的AI绘画网站Draft,重点是免费!不需要爬楼梯!
  2. Leaning method
  3. linux服务器搭建
  4. coot 突然打不开的解决方法
  5. 本科学计算机专业当海军可以分配什么兵种,当兵被分配到海军几率大吗 会分配到哪里...
  6. 智能优化算法:孔雀优化算法-附代码
  7. 用什么软件画流程图之流程图的绘制技巧介绍
  8. 投掷骰子的python代码_Python真好玩:循环的力量(上)
  9. 末日觉醒服务器端文件,CryoFall末日觉醒GM指令大全 服务器管理员指令汇总
  10. 编程英语:常见代码错误 error 语句学习(8)