把类的成员函数声明为友元函数,但不能访问私有成员的原因和解决办法
定义类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的私有成员时,这样定义没问题。
把类的成员函数声明为友元函数,但不能访问私有成员的原因和解决办法相关推荐
- C++友元函数 普通函数声明为友元函数
友元函数 如果在本类以外的其他地方定义了一个函数(这个函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数),在对本类进行声明时,在类体中用friend对该函数进行声明,此函数就称为本类的&q ...
- R语言dplyr包filter函数 Error in filter(., ) : 找不到对象的报错原因和解决办法
报错描述 当我们想使用dplyr包中的 filter 函数对指定的dataframe进行如下的行筛选时,R报错Error in filter(., ) : 找不到对象X.stage_id. ,提示我们 ...
- eclipse android 不能生成r类 appt错误,Ubuntu中Eclipse新建Android project提示缺失R文件的原因及解决办法...
环境: 64位Ubuntu12.04进行Android开发,sun-JDK1.7,官网下载的最新ADT-Eclipse-SDK集成包.JDK配置正确.SDK已更新,版本一致 问题: 第一次启动Ecli ...
- 友元函数可以访问私有成员吗_C++的友元函数和友元类
C++使用类对数据进行隐藏和封装,类的数据成员一般定义为私有成员,而将提供类与外界通讯接口的成员函数定义为公有的. C++类成员的三种访问权限: public:可以被该类中的函数.子类的函数.友元函数 ...
- public 函数_Chapter18:友元函数和友元类
这一章的问题从"如何畅通无阻的访问另一个类"开始,类的属性有private.protected.public,根据继承权限有不同的访问方式.但是类之间的关系不一定是继承,有时一个类 ...
- c语言friend函数,C++ friend友元函数和友元类
友元函数和友元类在实际开发中较少使用,想快速学习C++的读者可以跳过本节. 一个类中可以有 public.protected.private 三种属性的成员,通过对象可以访问 public 成员,只有 ...
- 基类的析构函数不能被继承。_为什么要把C++类中的析构函数声明为虚函数?
如题,当一个类为基类的时候,通常其析构函数被声明为虚函数,这是为啥? class BaseCls { public: BaseCls() { printf("BaseCls()n" ...
- 为什么静态成员函数可以访问私有成员变量?(访问控制是针对类而不是针对对象)
访问控制是针对类而不是针对对象 先看几个标准定义 A member of a class can be - private; that is, its name can be used only by ...
- java有没有友元函数_c++中友元函数理解与使用
在学习c++这一块,关于友元函数和友元类,感觉还是不好理解,但是井下心来,理解,需要把我一下几点. 首先讲友元函数. (1)友元函数: 1)C++中引入友元函数,是为在该类中提供一个对外(除了他自己意 ...
最新文章
- Windows服务器上Mqtt服务器EMQX的安装使用
- 尚学堂Spring视频教程(二):Spring控制反转
- java togglebutton_ToggleButton和Switch使用大全
- 突发!王思聪名下房产、汽车、存款等被查封
- iphone NSTimer
- python教程视频哪个好-Python教学视频哪个好?老男孩Python培训
- 【渝粤教育】国家开放大学2018年秋季 0032-21T农业经济学 参考试题
- SLAM精度测评(绘制比较相机轨迹)- EVO
- Visitor Pattern
- 山东计算机软考题库,软考习题库
- GNU Radio Pythpn
- 章文嵩-构建云计算平台的实践
- oracle赋权语句详解,Oracle GRANT 赋权详解
- 【子桓说】在BAT等大公司升职的人,都明白这几点
- 分部积分出现积回去的情况
- Unity Shader Graph 制作Grid网格效果
- 2.1微信小程序--比较数字大小
- 定时任务系列(3)-Quartz动态定时任务
- 组员大眼瞪小眼,forEach处理异步任务遇到的坑
- 【L2-031 深入虎穴】天梯赛L2系列详解