C++ 友元的认识

来源:互联网 发布:巴巴多斯大炮知乎 编辑:程序博客网 时间:2024/04/29 00:32

C++ 友元的认识

先附上基本和C++编程思想里第五章P134 ~ P135  差不多的代码供修改及以后 逐步理清概念
#include <iostream>
using namespace std;

class X; // 预先声明 不完全定义

class Y;
class Y{
public:
    void f(X*);
};

class X{
private:
    int i;
public:
    void initialize();
    int getI(){
        return i;
    }
    //四加一个friend东西。。
    friend void g(X*,int); //1.问:可以在外面修改x类中 i 的值么
    friend void Y::f(X*); //2.问:友元的对象指定为某个类里的一个成员函数
    friend class Z; //3.某个类作为X的友元类,对i是否是可以直接访问调用甚至修改i值?
    friend void h(); //4.外部函数是否可以直接访问X的私有成员?
    friend int main(); //ADDITIONAL 会不会就无视X的所有私有成员?

};

//普通X类里的成员函数的实现
void X::initialize(){
    i = 0;
}

void g(X* x,int i){
    x->i = i;
}

void Y::f(X* x){
    x->i = 1000;
}

class Z{
private:
    int j;
public:
    void initialize(){
        j = 1000;
    }
    void g(X* x){
        x->i = j;
    }
};

void h(){
    X x;
    x.i = 1000;
    cout<<"position 2 , i = "<<x.i<<endl;
}

问题一: 

                             

friend void g(X*,int);     //1.问:可以在外面修改x类中 i 的值么?


测试代码:


测试结果:


结论: 友元函数如果是主程序中某个函数,一旦声明友元将能够直接修改参数类中的private值 诸如这一情况 直接修改了x->i;

反例:假设未声明友元,情况又会怎么样呢?

这里在主函数里声明一个g2函数但是没有在class X里 加g2为友元函数

结果编译不同过,编译器锁定了Class X中的 i变量为private不可访问!


问题二


friend void Y::f(X*);   //2.问: 友元的对象指定为某个类里的一个成员函数,是否有修改X中 private变量i 的权力?


测试代码:

测试结果:

小结: 某个类的友元函数可以加入另一个类的成员函数。

这个反例不再举了,因为他的机制和问题一中的大致相同,再没有加为X友元函数之前 Y::f() 也是剥夺了访问X类的private变量权力


问题三:


friend struct Z; //3.某个类作为X的友元类,对i是否是可以直接访问调用甚至修改 i 值?


测试代码:

测试结果:

小结: 这个例子中是Z类作为 X类的一个友元类, 直接可以在函数中修改X所有的private变量


问题四:

    friend void h(); //4.外部函数是否可以直接访问X的私有成员?

测试代码:


测试结果:

小结: 外部函数如果申明为由原函数也可以直接访问到该类的私有成员。


总结以上四个问题的解决可以说涵盖了C++友元常用到的情况之后,其实友元friend这个符号,说白了就是开了一条直达某个类私有成员的通道。虽然调用起来更方便了,但是也破坏了封装,希望能总结出一个最合理的使用友元的度。


ADDITIONAL QUESTION !! 问题五

把main函数设为该类的友元类:


测试代码:

测试结果:

小结:非常犀利,把主函数 int main()加到 X 的友元函数之后,  main 函数完全解除 X类神秘的面纱,私有成员随便用。。 很强大!

原创粉丝点击