zoukankan      html  css  js  c++  java
  • 【C++ Primer】第十五章 友元、异常和其他 之一>友元和嵌套类

    一,友元

           1)可以将类作为友元,友元类的所有方法都可以访问原始类的私有成员和保护成员。

           2)下面例子介绍了 电视类和遥控器类,其中遥控器类为电视类的友元类

           3)注意:友元关系不具对称性。即 A 是 B 的友元,但 B 不一定是 A 的友元。 友元关系不具传递性。即 B 是 A 的友元,C 是 B 的友元,但是 C 不一定是 A 的友元。

    #include <iostream>
    using namespace std;
    class TV
    {
    private:
    	int state;// on or off
    	int volume; //assumed to be digitized
    	int maxchannel;// maximum number of channels
    	int channel;//current channel settings
    	int mode;//broadcast  or  cable
    	int input;//tv or vcr
    public:
    	friend class Remote;//遥控器类
    	enum{off,on}; //枚举
    	enum{minval,maxval=20};
    	enum{antenna,cable};
    	enum{tv,vcr};
    	
    	TV(int s=off,int mc=100):state(s),volume(5),maxchannel(mc),channel(2),mode(cable),input(tv){} //构造函数
    	
    	void onoff(){
    		state=(state == on)?off:on;
    	}	
    	bool ison()const{
    		return state == on;
    	}
    	bool volup();
    	bool voldown();
    	void chanup();
    	void chandown();
    	void set_mode(){
    		mode = (mode == antenna)?cable:antenna; 
    	} 
    	void set_input(){
    		input=(input == tv)?vcr:tv;
    	}
    	void settings()const;
    } ;
    
    class Remote//遥控器友元类
    {
    private:
    	int mode;
    public:
    	Remote(int m=TV::tv):mode(m){} //遥控的是电视而不是 vcr
    	bool volup(TV &t){  //遥控器的操作都是来源于电视对自身的操作 ,所以友元遥控器的方法都是调用电视的成员函数
    		return t.volup();
    	}	
    	bool voldown(TV &t){
    		return t.voldown();
    	}
    	void onoff(TV &t){
    		return t.onoff();
    	}
    	void chanup(TV &t){
    		return t.chanup();
    	}
    	void chandown(TV &t){
    		return t.chandown();
    	}
    	void set_chan(TV &t,int c){  //唯一需要作为友元的方法,因为它用来访问TV类的private成员
    		t.channel=c;
    	}
    	void set_mode(TV &t){
    		t.set_mode();
    	}
    	void et_input(TV &t){
    		t.set_input();
    	}
    	
    };
        /*下面是电视的成员方法实现*/
        bool TV::volup()
        {
        	if(volume<maxval)
        	{
    	    	volume++;
    	    	return true;
    	    }
    	    else
             	return false;
        }
    	bool TV::voldown()
    	{
    		if(volume>minval)
        	{
    	    	volume--;
    	    	return true;
    	    }
    	    else
             	return false;
    		
    	}
    	void TV::chanup()
    	{
    		if(channel<maxchannel)
    		  channel++;
    	    else
    		  channel=1;
    		
    	}
    	void TV::chandown()
    	{
    		if(channel>1)
    		  channel--;
    	    else
    		  channel=maxchannel;
    		
    	}
    	void TV::settings()const
    	{
    		cout<<"tv is "<<(state == off?"on":"off")<<endl;
    		if(state == on)
    		{
    			cout<<"volume setting ="<<volume<<endl;
    			cout<<"channel setting ="<<channel<<endl;
    			cout<<"Mode ="<<(mode == antenna?"cable":"antenna")<<endl;
    			cout<<"Input ="<<(input == tv?"vcr":"tv")<<endl;
    		}
    		
    	}
    	
    int main()
    {
    	TV s27;
    	cout<<"initinal settings for 27\" tv:\n";
    	s27.settings();
    	s27.onoff();
    	s27.chanup();
    	cout<<"adjust settings for 27\"tv:";
    	s27.settings();
    	
    	
    	return 0;
    }
    
    输出为:

    二,嵌套类

           1)嵌套与包含的区别

                 包含意味着将类对象作为另一个类的成员

                 对类进行嵌套,不创建类成员,而是定义了一种类型,该类型仅在包含嵌套类的类中使用。struct (结构)实际上是一种嵌套类

            2)嵌套类和访问权限

    声明位置 包含它的类是否可以使用 从包含它的类派生出来的类,是否可以使用 外部世界是否可以使用
    私有部分
    保护部分
    共有部分


  • 相关阅读:
    阿里巴巴数据库分库分表的最佳实践
    Tomcat控制台日志乱码解决方案
    区块链:多链体系在提升性能的同时,怎么去保证单链被攻击性问题
    在 CentOS 7 1801 中安装 PostgreSQL-11
    为什么即使现在生意不太好做,还是有一批批的人开始做生意?
    投资十几万可以做点什么生意?
    理发店真是一个暴利行业吗?
    今日头条是怎么盈利的?
    中国都有哪些著名的风投失败的案例?
    基于语音应用的10项最佳实践
  • 原文地址:https://www.cnblogs.com/secbook/p/2655025.html
Copyright © 2011-2022 走看看