https://github.com/jzplp/Cpp-Primer-Answer
-
練習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;
-
練習18.7
Blob類 書上的版本
實現了構造函數try語句塊
18.7 Blob.h程序代碼
18.7 測試程序代碼 -
練習18.8
Sales_data類 書上的版本
增加了noexcept說明
測試代碼僅本題使用
18.8 Sales_data.h程序代碼
18.8 Sales_data.cpp程序代碼
18.8 測試程序代碼
shared_ptr2類
模仿標準庫的shared_ptr,自己實現
增加了noexcept說明
18.8 shared_ptr2.h程序代碼
18.8 DebugDelete.h程序代碼
18.8 測試程序代碼
Vec類
增加了noexcept說明
18.8 Vec.h程序代碼
18.8 測試程序代碼
unique_ptr2類
模仿標準庫的unique_ptr,自己實現
增加了noexcept說明
18.8 unique_ptr2.h程序代碼
18.8 DebugDelete.h程序代碼
18.8 測試程序代碼
Blob類 書上的版本
增加了noexcept說明
18.8 Blob.h程序代碼
18.8 測試程序代碼
TextQuery類 書上的版本
Query和繼承類 書上的版本
增加了noexcept說明
18.8 TextQuery.h程序代碼
18.8 TextQuery.cpp程序代碼
18.8 Query.h程序代碼
18.8 Query.cpp程序代碼
18.8 測試程序代碼
Quote類 書上的版本
增加了noexcept說明
18.8 Quote.h程序代碼
18.8 Quote.cpp程序代碼
18.8 測試程序代碼
String類 自己定義 模仿書上的StrVec類
增加了noexcept說明
18.8 String.h 程序代碼
18.8 String.cpp 程序代碼
18.8 測試程序代碼 -
練習18.9
Sales_data類 書上的版本
增加了部分異常類和改寫了+=運算符
測試代碼僅本題使用
18.9 Sales_data.h程序代碼
18.9 Sales_data.cpp程序代碼
18.9 測試程序代碼 -
練習18.10
處理異常的版本見練習18.9
Sales_data類 僅本題使用
不處理異常的版本
18.10 Sales_data.h程序代碼
18.10 Sales_data.cpp程序代碼
18.10 測試程序代碼
未被捕獲異常,程序自動結束 -
練習18.11
因爲what函數一般在catch語句中使用,如果what函數引發了異常,那麼前一個異常沒有處理完畢,又來了新的異常,會很難處理 -
練習18.12
TextQuery類 僅本題使用
Query和繼承類 僅本題使用
增加了對應章的命名空間
18.12 TextQuery.h程序代碼
18.12 TextQuery.cpp程序代碼
18.12 Query.h程序代碼
18.12 Query.cpp程序代碼
18.12 測試程序代碼 -
練習18.13
希望使用單個文件範圍內的靜態變量時,可以使用未命名的命名空間 -
練習18.14
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) 正確
- 練習18.30
18.30 程序代碼