C++——友元、异常和其他

一、友元

  类并非只能拥有友元函数,也可以将类作为友元。在这种情况下,友元类的所有方法都可以访问原始类的私有成员和保护成员。另外,也可以做更严格的限制,只将特定的成员函数指定为另一个类的友元。哪些函数、成员函数或类为友元是由类定义的,而不能从外部强加友情。因此,尽管友元被授予从外部访问类的私有部分的权限,但它们并不与面向对象的编程思想相违背;相反,它们提高了公有接口的灵活性。

  1、友元类

  一般来说,如果希望一个类型的对象发生变化时,另一个其他类型的对象也相应地跟着产生变化,可以使用友元类来实现。

  要想使一个类成为另一个类的友元类,只需要在另一个类的公有、私有或保护部分声明如下语句即可:

    friend  class  Classname;

  友元类声明的位置无关紧要。

  下面定义Tv类和Remote类,其中Remote是Tv的友元类,通过Remote对象可以控制TV对象:

头文件:

 1 #include <stdio.h>
 2 #include <iostream>
 3
 4 class Tv{
 5 public:
 6     friend class Remote;
 7     enum {Off,On};
 8     enum {MinVal,MaxVal = 20};
 9     enum {Antenna,Cable};
10     enum {TV, DVD};
11
12     Tv(int s = Off, int mc = 125):state(s),volume(5),maxchannel(mc),channel(2),mode(Cable),input(TV){};
13     void onoff(){state ^= 1;}
14     bool ison(){return state == On;}
15     bool volup();
16     bool voldown();
17     void chanup();
18     void chandown();
19     void set_mode(){mode ^= 1;}
20     void set_input(){input ^= 1;}
21     void settings()const;
22 private:
23     int state;
24     int volume;
25     int maxchannel;
26     int channel;
27     int mode;
28     int input;
29 };
30 class Remote{
31 private:
32     int mode;
33 public:
34     Remote(int m = Tv::TV):mode(m){};
35     bool volup(Tv & t){return t.volup();}
36     bool voldown(Tv & t){return t.voldown();}
37     void onoff(Tv & t){t.onoff();}
38     void chanup(Tv & t){t.chanup();}
39     void chandown(Tv & t){t.chandown();}
40     void set_chan(Tv & t, int c){t.channel = c;};
41     void set_mode(Tv & t){t.set_mode();}
42     void set_input(Tv & t){t.set_input();}
43 };

实现文件:

 1 #include "TV.h"
 2 bool Tv::volup(){
 3     if (volume < MaxVal) {
 4         volume ++;
 5         return true;
 6     }
 7     return false;
 8 }
 9 bool Tv::voldown(){
10     if (volume > MinVal) {
11         volume --;
12         return true;
13     }
14     return false;
15 }
16 void Tv:: chanup(){
17     if (channel < maxchannel) {
18         channel++;
19         return;
20     }
21     channel = 1;
22 }
23 void Tv:: chandown(){
24     if (channel > 1) {
25         channel--;
26         return;
27     }
28     channel = maxchannel;
29 }
30 void Tv:: settings()const{
31     using namespace std;
32     cout << "TV is " << (state == Off?"Off":"On") << endl;
33     if (state == On) {
34         cout << "Volume setting = " << volume << endl;
35         cout << "Channel setting = " << channel << endl;
36         cout << "Mode = " << (mode == Antenna ? "antenna" : "cable") << endl;
37         cout << "Input = " << (input == TV? "TV" :"DVD") << endl;
38     }
39 }

main.cpp

 1 #include <iostream>
 2 #include "TV.h"
 3
 4 using namespace std;
 5
 6 int main(int argc, const char * argv[]) {
 7     Tv s42;
 8     cout << "Initial setting for 42\" TV:\n";
 9     s42.settings();
10     s42.onoff();
11     s42.chanup();
12     cout << "\nAdjusted settings for 42\" TV:\n";
13     s42.chanup();
14     cout << "\nAdjusted setting for 42\" TV:\n";
15     s42.settings();
16
17     Remote grey;
18     grey.set_chan(s42, 10);
19     grey.volup(s42);
20     grey.volup(s42);
21     cout << "\n42\"settings after using remote :\n";
22     s42.settings();
23
24     Tv s58(Tv::On);
25     s58.set_mode();
26     grey.set_chan(s58, 28);
27     cout << "\n58\" settings:\n";
28     s58.settings();
29     return 0;
30 }
31
32
33 输出结果:
34 Initial setting for 42" TV:
35 TV is Off
36
37 Adjusted settings for 42" TV:
38
39 Adjusted setting for 42" TV:
40 TV is On
41 Volume setting = 5
42 Channel setting = 4
43 Mode = cable
44 Input = TV
45
46 42"settings after using remote :
47 TV is On
48 Volume setting = 7
49 Channel setting = 10
50 Mode = cable
51 Input = TV
52
53 58" settings:
54 TV is On
55 Volume setting = 5
56 Channel setting = 28
57 Mode = antenna
58 Input = TV

 2、友元成员函数

  

时间: 2024-10-01 06:41:17

C++——友元、异常和其他的相关文章

Google&#39;s C++ coding style

v0.2 - Last updated November 8, 2013 源自 Google's C++ coding style rev. 3.274 目录 由 DocToc生成     头文件        #define用法        前向声明        内联函数        -inl.h文件        函数参数顺序        include的命名和顺序    作用域        命名空间            未命名空间            命名空间       

Google开发规范

v0.2 - Last updated November 8, 2013 源自 Google's C++ coding style rev. 3.274 目录 由 DocToc生成     头文件        #define用法        前向声明        内联函数        -inl.h文件        函数参数顺序        include的命名和顺序    作用域        命名空间            未命名空间            命名空间       

C++ Primer Plus

第1章 预备知识 第2章 开始学习C++ 第3章 处理数据 第4章 复合类型 第5章 循环和关系表达式 第6章 分支语句和逻辑运算符 第7章 函数-C++的编程模块 第8章 函数探幽 第9章 内存模型和名称空间 第10章 对象和类 第11章 使用类 第12章 类和动态内存分配 第13章 类继承 第14章 C++中的代码重用 第15章 友元,异常和其他 第16章 string类和标准模板库 第17章 输入,输出和文件 第18章 探讨C++新标准 附录A 计数系统 附录B C++保留字 附录C AS

C++ Primer Plus 第15章 友元、异常和其他

第15章 友元.异常和其他 1.友元不仅有友元函数,还能是友元类 还可以将类中的某一个成员函数指定为另一个类的友元 尽管友元被授予从外部访问私有部门的权限,单并不与面向对象编程思想相愽,相反,它们提高了公有接口的灵活性 2.类的成员函数作为其他类的友元,涉及到类的声明顺序. 还有一个函数作为两个类的友元 这方面内容看P607-611 3.嵌套类:在另一个类中声明的类被称为嵌套类 类嵌套与包含不一样.包含意味着将一个类对象作为另一个类的成员,而对类进行嵌套不创建类成员,而是定义了一种类型. 4.对

《C++ Primer Plus》第15章 友元、异常和其他 学习笔记

友元使得能够为类开发更灵活的接口.类可以将其他函数.其他类和其他类的成员函数作为友元.在某些情况下,可能需要前向声明,需要特别注意类和方法声明的顺序,以正确地组合友元.潜逃类是在其他类中生命的类,它有助于设计这样的助手类,即实现其他类,单必须是共有接口的组成部分.C++机场机制为处理拙劣的编程事件,如不适当的I/O失败等,提供了一种灵活的方式.引发异常将终止当前值性的函数,将控制权传给匹配的catch块.catch块紧跟在try块的后面,为捕获异常,直接或间接导致异常的函数调用必须为与try块中

【C/C++学院】0825-类模板/final_override/类模板与普通类的派生类模板虚函数抽象模板类/类模板友元/位运算算法以及类声明/Rtti 实时类型检测/高级new创建/类以及函数包装器

类模板 类模板多个类型默认类型简单数组模板 #pragma once template <class T=int>//类模板可以有一个默认的值 class myArray { public: myArray(); ~myArray(); }; #include "myArray.h" template <class T=int>//每一个函数都需要加上一个默认的值 myArray<T>::myArray() //类模板成员函数在外部,需要加载类型初始

类模板,多种类型的类模板,自定义类模板,类模板的默认类型,数组的模板实现,友元和类模板,友元函数,类模板与静态变量,类模板与普通类之间互相继承,类模板作为模板参数,类嵌套,类模板嵌套,类包装器

 1.第一个最简单的类模板案例 #include "mainwindow.h" #include <QApplication> #include <QPushButton> #include <QLabel> template<class T> class run { public: T w; void show() { w.show(); } void settext() { w.setText("A"); }

使用 IDEA 创建 Maven Web 项目 (异常)- Disconnected from the target VM, address: &#39;127.0.0.1:59770&#39;, transport: &#39;socket&#39;

运行环境: JDK 版本:1.8 Maven 版本:apache-maven-3.3.3 IDEA 版本:14 maven-jetty-plugin 配置: <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <configuration> <webAppSourceDirectory>${pro

mybaits非配置原因,导致SqlSession was not registered for synchronization异常

今天运行程序时报了 SqlSession [[email protected]] was not registered for synchronization because synchronization is not active [11:03:17]-Closing non transactional SqlSession [[email protected]] 由于异常是集中处理的,所以报了这样的错误,查了半天,网上结果都是说配置文件出错的,可是我的项目配置文件肯定是没错的,因为项目都开