stack unwinding Exception raised Program looks if the

  • Slides: 25
Download presentation

堆疊輾轉開解(stack unwinding) Exception raised Program looks if the function can handle the exception it

堆疊輾轉開解(stack unwinding) Exception raised Program looks if the function can handle the exception it self If not->program will immediately terminates the function and check if the caller will handle it If not->terminate the caller and check the caller’s caller……until main function

rethrow 當catch無法徹底處理某個異常,他會決定讓更 上層的函式來處理,這個時候就會用到複拋 (rethrow) throw只能出現在catch裡或catch呼叫的函式中。 如果沒有,會喚起terminate() catch (my_error &e. Obj) { // reference type

rethrow 當catch無法徹底處理某個異常,他會決定讓更 上層的函式來處理,這個時候就會用到複拋 (rethrow) throw只能出現在catch裡或catch呼叫的函式中。 如果沒有,會喚起terminate() catch (my_error &e. Obj) { // reference type e. Obj. status = severe. Err; // status的內容變成了 severe. Err throw; } catch (other_error e. Obj) { // nonreference type e. Obj. status = bad. Err; // 修改的是異常物件的複本 throw; // status的內容並沒有改變 }

使用auto_ptr class 要記得 #include <memory> 建立auto_ptr時,要指定目標物件之型態 auto_ptr<int> i. Ptr (new int(100)); auto_ptr<string> s. Ptr

使用auto_ptr class 要記得 #include <memory> 建立auto_ptr時,要指定目標物件之型態 auto_ptr<int> i. Ptr (new int(100)); auto_ptr<string> s. Ptr (new string("caterpillar")); 如果沒有設定任何初值,auto_ptr物件就不指向 任何物件 auto_ptr<int> i. Ptr ;

17. 2命名空間 以namespace開頭,後面接著namespace名稱 namespace cplus_primer { int i; double j; class Query { public:

17. 2命名空間 以namespace開頭,後面接著namespace名稱 namespace cplus_primer { int i; double j; class Query { public: Query(const std: : string&); }; } 每個命名空間都是一個scope 同一個namespace內的成員可直接存取,外部程 式碼要取用時,必須明確指出其namespace cplus_primer: : Query q = cplus_primer: : Query(“hello”);

定義Namespace的成員 定義於此命名空間的成員可以使用非全飾名稱 namespace cplus_primer { std: : istream& operator>>(std: : istream& in, Sales_item& s)

定義Namespace的成員 定義於此命名空間的成員可以使用非全飾名稱 namespace cplus_primer { std: : istream& operator>>(std: : istream& in, Sales_item& s) { //. . . } } 定義於namespace之外的成員必須使用全飾名 cplus_primer: : operator+(const Sales_item& lhs, const Sales_item& rhs) { Sales_item ret(lhs); //. . . } global namespace被隱寓宣告並存在每個程式中 : : member_nam e

Nested Namespaces namespce外圍宣告的名稱會被內圈相同名稱遮蔽 namespace cplus_primer { namespace Query. Lib { class Query { /*.

Nested Namespaces namespce外圍宣告的名稱會被內圈相同名稱遮蔽 namespace cplus_primer { namespace Query. Lib { class Query { /*. . . */ }; } namespace Bookstore { class Item_base { /*. . . */ }; class Bulk_item : public Item_base { /*. . . */ }; } } 外圍程式碼要透過全飾名稱才能存取 cplus_primer: : Query. Lib: : Que ry 目的:防止程式庫中某部分的名稱與另一部分的名稱 發生衝突

Unnamed Namespace unnamed namespace用來宣告檔案中的local物 體,在使用時不需使用其它飾名 由於unnamed namespace的特性,當定義於檔 案最外層時,要和global中的變數名稱不同 #include <iostream> using namespace std; namespace

Unnamed Namespace unnamed namespace用來宣告檔案中的local物 體,在使用時不需使用其它飾名 由於unnamed namespace的特性,當定義於檔 案最外層時,要和global中的變數名稱不同 #include <iostream> using namespace std; namespace { const int i = 4; int variable; } int main() { cout << i << endl; variable = 100; return 0; } #include <iostream> using namespace std; namespace { const int i = 4; } int i = 2; int main() { cout << i << endl; // error variable = 100; return 0; }

using指令與作用域 namespace blip { int bi = 16, bj = 15, bk = 23;

using指令與作用域 namespace blip { int bi = 16, bj = 15, bk = 23; } int bj = 0; //宣告沒問題,在使用bj的時候才會出現衝突 void manip() { //使用using,把blip內的名稱加到global中 using namespace blip; ++bi; // 意同blip: : bi = 7; ++bj; // 錯誤:不知道是global還是blip ++: : bj; // 意同global bj = 1 ++blip: : bj; // 意同blip: : bj = 16 int bk = 97; // 宣告了一個新的local物件bk,掩蓋了 blip: : bk ++bk; // local bk = 98 }

Pointer轉換 Derived class的pointer可以自動轉成base class 的pointer 例:panda的pointer可以轉為Zoo. Animal, Bear或 Endangered的pointer // operations that take references

Pointer轉換 Derived class的pointer可以自動轉成base class 的pointer 例:panda的pointer可以轉為Zoo. Animal, Bear或 Endangered的pointer // operations that take references to base classes of type Panda void print(const Bear&); void highlight(const Endangered&); ostream& operator<<(ostream&, const Zoo. Animal&); Panda ying_yang("ying_yang"); // create a Panda object print(ying_yang); // passes Panda as reference to Bear highlight(ying_yang); // passes Panda as reference to Endangered cout << ying_yang << endl; // passes Panda as reference to Zoo. Animal

如果有overload function void print(const Bear&); void print(const Endangered&); ================== Panda ying_yang("ying_yang"); print(ying_yang); // error:

如果有overload function void print(const Bear&); void print(const Endangered&); ================== Panda ying_yang("ying_yang"); print(ying_yang); // error: ambiguous Print要明確指出要用的版本 Bear: : print Endangered: : print ================== std: : ostream& Panda: : print(std: : ostream &os) const { Bear: : print(os); // print the Bear part Endangered: : print(os); // print the Endangered part return os; }

虛擬繼承的宣告 class A { // 實作 }; class B 1 : virtual public A

虛擬繼承的宣告 class A { // 實作 }; class B 1 : virtual public A { // 虛擬繼承 // 實作 }; class B 2 : virtual public A { // 虛擬繼承 // 實作 }; class C : public B 1, public B 2 { // 實作 };

實例 class Base { void Echo() { printf("Echo from Base"); } }; class Middle

實例 class Base { void Echo() { printf("Echo from Base"); } }; class Middle 1 : public Base {} class Middle 2 : public Base {} class Child : public Middle 1, Middle 2 {} void main() { Child c; c. Echo(); //錯誤,不知道是哪一個 } class Base { void Echo() { printf("Echo from Base"); } }; class Middle 1 : virtual public Base {} class Middle 2 : virtual public Base {} class Child : public Middle 1, Middle 2 {} void main() { Child c; c. Echo(); // 正確,函數來自同一個base class }