zoukankan      html  css  js  c++  java
  • 友元

    友元



    写在前面

      类的主要特点之一就是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。但是,有时候需要在类的外部访问类的私有数据成员,怎么办呢?
      解决办法是使用友元函数,友元函数时一种特权函数c,C++允许这个特权函数访问私有成员。这一点我们可以用生活中的例子来看:   比如你的家有客厅,有卧室,客厅是public的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是,你可以允许你的好朋友进去。
      进程员可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元。

    1.全局函数做友元函数

    友元语法

    • friend关键字只出现在声明处
    • 其他类、类成员函数、全局函数都可以声明为友元
    • 友元函数不是类的成员,不带this指针
    #include <iostream>
    #include<string>
    using namespace std;
    
    
    class Home
    {
    public:
    	friend void test(Home *home);
    	Home()
    	{
    		this->bedroom = "卧室";
    		this->sittingroom = "客厅";
    	}
    	string sittingroom;//客厅
    private:
    	string bedroom;//卧室
    
    	
    };
    
    
    void test(Home *home)
    {
    	cout << "你的好友正在访问" << home->sittingroom << endl;
    	cout << "你的好友正在访问" << home->bedroom << endl;
    }
    int main()
    {
    	Home *home=new Home;
    	test(home);
    }
    

    输出结果如下:

    从输出结果可以看出,当全局函数作为声明为友元函数之后,全局函数也可以访问类的私有成员。

    2.整个类做友元类

    #include <iostream>
    #include<string>
    using namespace std;
    
    
    class Home
    {
    public:
    	friend class Good_Friend;
    	Home()
    	{
    		this->bedroom = "卧室";
    		this->sittingroom = "客厅";
    	}
    	string sittingroom;//客厅
    private:
    	string bedroom;//卧室
    
    	
    };
    
    class Good_Friend
    {
    public:
    	Good_Friend(string name)
    	{
    		this->name = name;
    	}
    	void visit()
    	{
    		cout << "好友"<<this->name<<"正在拜访" << this->home.sittingroom << endl;
    		cout << "好友"<<this->name<<"正在拜访" << this->home.bedroom << endl;
    	}
    
    private:
    	Home home;
    	string name;
    };
    
    
    void test()
    {
    	Good_Friend frend("Aoki");
    	frend.visit();大专栏  友元>
    
    
    }
    int main()
    {
    	test();
    }
    
    

      输出结果如下:

      将好友类声明为友元类之后,好友类的对象可以访问Home类的私有成员。
      在友元类中我们应当注意:

    1. 友元关系不能被继承
    2. 友元关系是单向的
    3. 友元关系不具有传递性

    C++是纯面向对象的吗?
      如果一个类被声明为friend ,意味着它不是这个类的成员函数,却可以是修改这个类的私有成员,而且必须列在类的定义中,因此它是一个特权函数。C++不是完全的面向对象语言,而是一个混合产品。增加friend关键字只是用来解决一些实际问题,这也说明这种语言是不纯的。毕竟C++设计的目的是为了实用性,而不是追求理想的抽象。
    -———《Think in C++》

    </br>

    #include <iostream>
    #include<string>
    using namespace std;
    
    class Home;
    class Good_Friend
    {
    public:
    	Good_Friend(string name);
    	void visit();
    	void visit2();
    private:
    	Home *home;
    	string name;
    };
    
    class Home
    {
    	friend void  Good_Friend::visit();
    public:
    	Home();
    public:
    	string sittingroom;
    private:
    	string bedroom;
    };
    
    Good_Friend::Good_Friend(string name)
    {
    	home = new Home;
    	this->name = name;
    }
    
    void Good_Friend::visit()
    {
    	cout << "你的好友" << this->name << "正在访问" << this->home->sittingroom << endl;
    	cout << "你的好友" << this->name << "正在访问" << this->home->bedroom << endl;
    }
    
    void Good_Friend::visit2()
    {
    	cout << "你的好友"<<this->name<<"正在访问" << this->home->sittingroom << endl;
    	//cout << "你的好友" << this->name << "正在访问" << this->home->bedroom << endl;
    }
    
    Home::Home()
    {
    	this->sittingroom = "客厅";
    	this->bedroom = "卧室";
    }
    
    void test()
    {
    	Good_Friend frien("Aoki");
    	frien.visit();
    	frien.visit2();
    }
    
    int main()
    {
    	test();
    	return 0;
    }
    
    

     &emsp当我们试图使用一个没有声明为Home类友元的成员函数去访问Home的私有成员时,编译器报错如下:

    正确是输出结果如下:

      虽然我现在将visit()函数定义为Home类的友元,但是事情并没有这么简单地结束,因为当我第一次定义友元函数时,编译器莫名其妙地报错。那么,编译器报错的原因是什么呢?
      当我尝试着把成员函数的声明与定义分开的时候,编译器显示没有错误。这也就告诉我们,在声明成员函数的时候,将声明与定义分开放,编译器会更好地处理。







    The End

  • 相关阅读:
    使用Apache的ab工具进行压力测试
    Effective Java开篇
    mysql删除同一表中重复字段记录
    正则表达式的元字符匹配
    几个学习git的地方
    创建和销毁对象
    遇到多个构造器参数时要考虑用构建器
    Java的类和接口
    转:流言粉碎机:每天对着电脑46小时的人必看
    页面选中文字弹出层,点击层中文字或者图片触发事件
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12014194.html
Copyright © 2011-2022 走看看