15.7 复习题
1.下面建立友元的尝试有什么错误?
a.
class snap
{
friend clasp;
...
};
class clasp{ ... };
b.
class cuff
{
public:
void snip(muff&){..}
...
};
class muff
{
friend void cuff::snip(muff& );
...
};
c.
class muff
{
friend void cuff::snip(muff & );
...
};
class cuff
{
public:
void snip(muff&){...}
...
};
a.clasp类不可见,需要向前声明
class clasp;
class snap
{
friend clasp;
...
};
class clasp{ ... };
b.muff类不可见,需要向前声明
class muff;
class cuff
{
public:
void snip(muff&){..}
...
};
class muff
{
friend void cuff::snip(muff& );
...
};
c.cuff类不可见,应该在muff之前声明,muff要加个向前声明。
class muff;
class cuff
{
public:
void snip(muff&){...}
...
};
class muff
{
friend void cuff::snip(muff & );
...
};
2.您知道了如何建立相互类友元的方法。能够创建一种更为严格的友情关系,即类B只有部分成员是类A的友元,而类A只有部分成员是类B的友元吗?请解释原因。
不能,要指定部分友元,要知道类的细节,总有一个先后顺序的。所以无法实现。
3.下面的嵌套类声明中可能存在什么问题?
class Ribs
{
private:
class Sauce
{
int soy;
int sugar;
public:
Sauce(int s1, int s2):soy(s1), sugar(s2){}
}
...
};
Sauce的成员无法被访问。
4.throw和return之间的区别何在?
return是正常的返回,而且返回函数被调用的地方,然后继续往下执行。
throw是抛出异常,沿着调用的当前序列回溯一路往上,直到被捕抓到为止,然后执行catch块的语句。
5.假设有一个从异常基类派生来的异常类层次结构,则应按什么样的顺序放置catch块?
从派生类开始,一直到基类,再到上一层的基类。
6.对于本章定义的Grand、Superb 和Magnificent类,假设pg为Grand*指针,并将其中某个类的对象地址赋给了它,而ps为Superb*指针,则下面两个代码示例的行为有什么不同?
if(ps = dynamic_cast<Superb*>(pg)
ps->say();
if(typeid(*pg) == typeid(Superb))
((Superb*) pg)->say();
对于Superb的子类,第一个例子是有效的,if内为true,但是第二个例子就无效了,if内为false。
7.static_cast运算符与dynamic_cast运算符有什么不同?
static_cast是编译时检测,允许向上转换和向下转换,还允许枚举类型和整形之间以及数值类型之间的转换,可以转换编译器进行隐式转换的类型
dynamic_cast是运行时转换,只允许沿着层次结构向上转换,如果不行的话就返回空指针。