( a) 类型是range_error
( b) 被抛出的异常对象是对指针p解引用的结果,类型与p的静态类型相同,为exception
若写成throw p,则异常对象是exception*
在释放资源前发生了异常,导致内存泄漏
方法一
将可能发生异常的代码放在try 中,捕获异常后进行释放
void exercise ( int * b, int * e)
{
vector< int > v ( b, e) ;
int * p = new int [ v. size ( ) ] ;
try
{
ifstream in ( "ints" ) ;
}
catch
{
delete p;
}
}
方法二
定义一个类来封装数组的分配和释放,因为析构函数总会被执行
这里的三个异常都因为继承关系而相关
runtime_error继承exception,overflow_error继承runtime_error
所以catch 子句应该从最低派生类型到最高派生类型排序,这样派生类的处理代码能在基类之前处理派生类独有的东西
try {
. . .
} catch ( overflow_error eObj)
{
. . .
} catch ( const runtime_error & re)
{
. . .
} catch ( exception)
{
. . .
}
int main ( )
{
try
{
. . .
} catch ( const exception & e)
{
cerr << e. what ( ) << endl;
abort ( ) ;
}
}
( a) throw new exceptionType ( ) ;
( b) throw 1234 ;
( c) throw 1234 ;
( b) List继承了两次
先执行A的构造函数,然后执行B的构造函数,再执行C的构造函数
之后执行X的构造函数,再执行Y的构造函数,然后执行Z的构造函数
最后执行自己的构造函数
( a) 允许
( b) 允许
( c) 允许
( d) 允许
pb-> print ( ) ;
pb-> toes ( ) ;
pb-> currdle ( ) ;
pb-> highlight ( ) ;
delete pb;
( a) 调用MI的print
( b) 调用MI的print
( c) 调用MI的print
( d) ( e) ( f) 因为是虚析构,所以会执行MI的析构。析构顺序和构造顺序相反
MI-> D2-> Base2-> D1-> Base1
MI类定义了自己的print,不会出现二义性问题
( a) ival、dval、cval、fval、sval、ival、dvec和print
( b) Base1:: dval和Derived:: dval print
( c) MI:: dval = Base1:: dval + Derived:: dval;
( d) fval = dvec[ dvec. size ( ) - 1 ] ;
( e) sval[ 0 ] = cval;
使用void bar ( char ) 和ival不需要限定符
访问foo和cval都需要限定符
( a) Class-> Base-> D1-> D2-> MI-> Class-> Final。析构函数相反
( b) 一个Base部分,两个Class部分
( c) 中
( a) 错误,不能用派生类指针指向基类对象
( b) 不确定
( c) 错误,不能用指向基类的指针给派生类指针赋值