100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 把类的成员函数声明为友元函数 但不能访问私有成员的原因和解决办法

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

时间:2021-09-01 17:04:47

相关推荐

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

定义类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的私有成员时,这样定义没问题。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。