Skip to content

Latest commit

 

History

History
365 lines (332 loc) · 9.2 KB

chapter-18-answer.md

File metadata and controls

365 lines (332 loc) · 9.2 KB
  • 练习18.1
    (a) range_error
    (b) exception
    改写(b) exception *

  • 练习18.2
    vector正常析构,文件正常关闭,但是指针p指向的内容不会被释放

  • 练习18.3

方法1 : 用一个类封装起来  
class pointerArr
{
public:
    void pointerArr(int * pt) : p(pt) { }
    ~pointerArr() { delete [] p; }
private:
    int * p;
}
void exercise(int * b, int * e)
{
    vector<int> v(b, e);
    pointerArr p = new int[v.size()];
    ifstream in("ints");
}

方法2 : 在本函数内进行处理  
void exercise(int * b, int * e)
{
    int *p =new int[v.size()];
    try
    {
        vector<int> v(b, e);
        ifstream in("ints");
    }
    catch(someErr r)
    {
        delete [] p;
    }
    
}
  • 练习18.4
    基类会匹配了派生类的所有类型,下面的catch永远不会被匹配
try
{
    //...
}catch(overflow_error eobj)
{ //... }
catch(const runtime_error & re)
{ //... }
catch(exception)
{ //... }
  • 练习18.5
int main()
{
    try
    {
        //...
    }catch(const runtime_error &e)
    {
        std::cerr << e.what() << std::endl;
        abort();
    }
    catch(const logic_error &e)
    {
        std::cerr << e.what() << std::endl;
        abort();
    }
    catch(exception &e)
    {
        std::cerr << "error!" << std::endl;
        abort();
    }
}
  • 练习18.6
(a) throw new exceptionType();
(b) 任何正确的throw表达式都能被捕获
(c) throw 3;
mathLib::MatrixLib::matrix mathLib::MatrixLib::matrix::operator*(const matrix &, const matrix &);
  • 练习18.15
    using指示是让命名空间整个暴露在当前作用域中。
    using声明仅仅让命名空间中的单个成员暴露在当前作用域中。
    还有更多细节的差别

  • 练习18.16
    位置1出现using声明:
    出现命名冲突,ivar是一个当前作用域的变量,也是命名空间Exercise中的变量声明到当前作用域
    位置2出现using声明:
    出现命名冲突,dvar是一个当前作用域的变量,也是命名空间Exercise中的变量声明到当前作用域
    位置1出现using指示:
    manip函数中的++ivar出现调用的二义性,ivar是一个外层作用域的变量,也是命名空间Exercise中的变量指示到外层作用域
    位置2出现using指示:
    manip函数中的++ivar出现调用的二义性,ivar是一个外层作用域的变量,也是命名空间Exercise中的变量指示到外层作用域

  • 练习18.17
    下面的代码都是测试错误的代码,仅本题使用
    位置1出现using声明:
    18.17 using1测试程序代码
    错误信息:

[Error] 'ivar' is already declared in this scope

位置2出现using声明:
18.17 using2测试程序代码
错误信息:

In function 'void manip()':
[Error] redeclaration of 'double dvar'
[Note] previous declaration 'double Exercise::dvar'

位置1出现using指示:
18.17 using3测试程序代码
错误信息:

In function 'void manip()':
[Error] reference to 'ivar' is ambiguous
[Note] candidates are: int ivar
[Note] int Exercise::ivar

位置2出现using指示:
18.17 using4测试程序代码
错误信息:

In function 'void manip()':
[Error] reference to 'ivar' is ambiguous
[Note] candidates are: int ivar
[Note] int Exercise::ivar

与上一题的回答一致

  • 练习18.18
    使用std的版本,因为using声明,所以std::swap在本作用域中,而自定义的swap函数在外层作用域中,因此被隐藏了

  • 练习18.19
    直接使用标准库的版本

  • 练习18.20

匹配的函数为:
void compute(int);
可行函数和对应的转换:
void primerLib::compute(const void *);
0 转换为 nullptr
void compute(int);
类型符合
void compute(double, double = 3.14);
int 转换为 double
void compute(char *, char * = 0);
0 转换为 nullptr

如果将using声明放到computer的调用点之前,那么候选函数只有:
void primerLib::compute(const void *);
0 转换为 nullptr
  • 练习18.21
(a) CADVehicle类public继承CAD类,private继承Vehicle类  
(b) 错误,重复继承同一个类  
(c) iostream类public继承istream类,public继承ostream类  
  • 练习18.22
    按照执行完成的顺序:
A-B-C-X-Y-Z-MI
  • 练习18.23
    (a) 允许
    (b) 允许
    (c) 允许
    (d) 允许

  • 练习18.24

pb->print();
正确,调用Panda::print()
pb->cuddle();
错误
pb->highlight();
错误
delete pb;
正确,调用Panda::~Panda()
  • 练习18.25
(a) MI::print()
(b) MI::print()
(c) MI::print()
(d) MI::~MI()
(e) MI::~MI()
(f) MI::~MI()
  • 练习18.26
因为在MI的作用域中只找到void print(std::vector<double>)函数,因此参数类型不匹配。
MI中增加函数
void print(int i) const
{
    Base1::print(i);
}
  • 练习18.27
不看成员函数
(a) 
函数作用域:
int dval
double cval
MI类作用域:
int * ival
std::vector<double> dvec
Derived类作用域:
string sval
Base1类作用域:
无
Base2类作用域:
double fval
剩下的名字应该都是隐藏不可见的  
(b)
不存在
(c)
dval = Base1::dval + Derived::dval;
(d)
假设MI::dvec的长度至少为1
Base2::fval = MI::dvec[MI::dvec.size() - 1];
(e)
Devired::sval = Base1::cval + Devired::sval; 
  • 练习18.28
无需前缀限定符的:
Devired2::ival
void Devired1::bar()
需要前缀限定符的:
Base::ival
void Base::bar(int)
void Derived1::foo(char)
Derived1::cval
void Derived2::foo(int)
Derived2::cval
  • 练习18.29
    (a) 构造函数执行次序,按照结束的时间排序:
    Class, Base, D1, D2, MI, Class, Final
    析构函数执行次序,按照结束的时间排序:
    Final, MI, D1 D2 Base Class, Class (b) 1个Base部分,2个Class部分
    (c)
(a) 错误
(b) 正确  
(c) 正确  
(d) 正确