当前位置: 首页 > C/C++, cpp > 正文

友元,异常和其它

友元,异常和其它

友元类于友元方法

之前我们说的函数,成员函数或类为友元只能说是有类定义的,从外部来看并没有什么“友情”,假设电视机和遥控器,遥控器可以对电视机产生影响,但是电视机与遥控器既不是is-a 关系也不是has-a 关系,我们该如何定义这种情况呢?此时需要遥控器这个类变成电视机的友元类,只有这样电视机才能被遥控器所影响,当然你也可以通过一个更大的类把遥控器和电视机封装起来。

友元类:
声明如下:
friend class Remote;
以电视机与遥控器的实例来说如下:

class Tv{
friend class Remote;
…….
…….
};

友元位于公有,私有或者保护部分,其所在位置无关紧要,当然遥控器类需要让编译器知道有Tv类,编译器才能识别处理遥控器类,最简单的方法就是将TV 类声明在遥控器类之前,还有一个方法就是向前声明,这个方法我们一会在说。
注意:也可以使用更大型的类来包含这几个类,但是一个遥控器可以控制多台电视机的属性,确只有友元类的方式才可以表现。

友元成员函数:

当然我们可以使一个函数成为友元成员函数让一个特定的函数去成为友元函数也有利于保护数据的安全性,体现C++的隐藏数据的特性。
方法如下:
我们只需要在Tv类中声明这个友元函数,举例如下:
class TV{
friend void Remote::set_chan(Tv & t,int c);
…..
};
在声明这个类的时候我们需要明确的指出这个类的作用域。但是我们声明的顺序就需要重新排列下了,如果继续按照先声明TV 那么编译器看到Remote 后,但是前边却并没有看到这个类的定义编译器直接懵逼然后报错,所以我们需要做如下声明:
class Tv; /*这就是向前声明*/
class Remote{
……
};
class Tv{
…….
};
注意:我们需要在编译器看到函数被声明为友元之前将它的函数定义先声明定义。

其他友好关系:
有的情况下,函数需要访问两个类的私有数据,即使相互会访问的情况,我们可以将他们作为两个类的友元更为合理。

嵌套类:
在C++中,可以将类声明在另一个类中,在另一个类中声明的类被成称为嵌套类,它提供新的类型作用域来避免名称混乱。包含类的成员函数可以创建和使用被嵌套类的对象;而仅当声明位于公有部分,才能在包含类的外面使用嵌套类,而且必须使用作用域解析符。

嵌套类的访问权限:

嵌套类,结构和枚举的作用域特征
声明位置 包含它的类是否可以使用它         从包含类派生来的类是否可以使用它                      外部世界是否可以使用它

私有部分 是                                                      否                                                                                 否

保护部分 是                                                      是                                                                                 否

公有部分 是                                                       是                                                                                 是,但是必须通过限定符
模板中也是可以嵌套类的

异常:

异常机制:C++异常是对程序运行过程中发生的异常情况的一种响应,异常提供了将控制权从程序的一个部分转移到另一个部分的途径。
简单来说就是:
try{
……..
…….
}catch(){
…….
…….
}
程序块
具体说,程序进入try块开始程序,当遇到异常的时候,throw 抛出异常,然后被catch ()捕获,进一步使程序转移到异常处理部分去。
异常类型可以是字符串或其他类型,但是通常是类类型,执行throw 语句类似返回语句,因为它的程序也将停止执行,因为它也将终止函数的执行,但是并不将控制权返回给调用程序,而是导致程序按照调用序列后退,直到找到包含try块的函数。这里我们来说说

堆栈解退。
通常函数一个调用一个,则函数的返回地址都被压入栈中,当函数返回时,一级一级的退出函数堆栈,但是异常触发时,函数结束也开始释放堆栈中内存但是不会在释放第一返回地址后停止,而是继续释放堆栈,直到找到一个位与try块内的返回地址,然后将控制权交给块尾的异常处理程序,对与堆栈内部的自动类对象,类的析构函数都将被调用,但是如果遇到new分配的对象,我们需要在处理程序中手动删除,因为程序自己只会释放指针而不会删除new 的内存。
接着catch 捕获到相应的异常,这里需要注意下异常的捕获规则,假设有一个以异常类层次结构,并分别处理不同的异常类型,则使用基类引用将能够捕获任何异常对象;而使用派生类对像只能捕获它所属类及从这个类中派生而来的对象。引发异常对象将被第一个与之匹配的cath块捕获,这意味着catch块的排列顺序应该与派生顺序相反。

几个操作符:

dynamic_cast 操作符将使用一个指向基类的指针来生成一个指向派生类的指针,失败返回0;
typeid 操作符返回一个指出对象类型的值
type_info 结构存储了有关特定类型的信息,即typeid 返回值
const_cast 暂时去除变量的const 限定符效果
static_cast 转换本就可以隐式转换的行为
reinterpret_cast 类似与强制转换

本文固定链接: http://zmrlinux.com/2016/01/29/%e5%8f%8b%e5%85%83%ef%bc%8c%e5%bc%82%e5%b8%b8%e5%92%8c%e5%85%b6%e5%ae%83/ | Kernel & Me

该日志由 root 于2016年01月29日发表在 C/C++, cpp 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: 友元,异常和其它 | Kernel & Me
【上一篇】
【下一篇】