C++友元與異常

C++ Primer Plus讀書筆記

友元

  • 友元不僅可以是一個函數,並且可以是類,友元類的所有方法都可以訪問原始類的私有成員和保護成員。同時,可以做更加細緻的限定:只將特定的成員函數指定爲一個類的友元。

1.友元類

  • 友元類在聲明的時候需要在被調用的類中聲明friend,此後即在這個friend類中隨意訪問原來類中的private成員了。

  • 也就是說,在某個類中(我)聲明另外一個類是朋友,那麼這個朋友就可以用我這個類的private。

class ZhuMeng
{
public:
    friend class yanyiquan;
private:
    int a;
};

class yanyiquan
{
public:
    void get_a(ZhuMeng & t){t.a = 1;}
    // 如果是隻規定一部分函數作爲友元,則
    friend ZhuMeng::a;
    //並且不需要在ZhuMeng類中聲明class是friend的。
};
  • 友元類是單向的,一個類是另一個類的友元,但是另一個類不一定是這個類的友元。

  • 友元函數在原始類中應只聲明,將定義放在實際定義TV類之後。因爲編譯器必須在瞭解原始類之後,才能處理他的友元類,因此是需要前向聲明的。

  • 就以TV和Remote兩個類爲例,Remote類中的方法提到了TV類中的對象,因此TV類需要定義在remote類之前,但是在TV類中,又無法知道Remote是一個類,這樣就產生了循環依賴
class Tv;

class Remote{…};

class Tv{…};
  • 舉個例子:當將一個類A的成員函數A::F設置成類B的友元時,需要預先定義類A,否則不能將A::F指定爲友元。而在定義B之後,才能定義A::F,因爲A::F被設爲 友元正是爲了訪問類B的成員函數。所以,可以按照如下的順序:

    1. 聲明類B
    2. 定義類A,聲明但不實現A::F
    3. 定義類B,設置A::F爲友元
    4. 實現A::F
#include<iostream>
#include<cstdlib>
using namespace std;

class Screen;//前向聲明
class Window_Mgr
{
public:
  void reloacate(Screen& s);
};

class Screen
{
  friend void Window_Mgr::reloacate(Screen& s);//必須先定義Window_Mgr,才能將Window_Mgr::relocate設爲友元
public:
  Screen(int _x, int _y): x(_x), y(_y){};
  void print()
  {
      cout <<"x: " <<x <<",y: "<<y <<endl;
  }
private:
  int x;
  int y;
};

void Window_Mgr::reloacate(Screen& s)
{
  s.x++;
  s.y++;
}

int main(int argc, char* argv[])
{
  Screen s(0, 0);
  Window_Mgr mgr;
  mgr.reloacate(s);
  s.print();
  system("pause");
  return 0;
}
  • 想要設置兩個互爲友元的類,則需要在類中互相寫friend關鍵字,同時也要考慮循環依賴的問題,把實現放在後面,也就是實現之前必須先讓編譯器知道另一個類的內容,如果只是聲明,則只需要前向聲明即可。

2.嵌套類

  • 類嵌套的意思就是將一個類定義在另外一個類中,與上面寫的ZhuMeng類是差不多的,外界能不能使用這個被嵌套的類,則取決於這個類被聲明的位置是public還是private。與一般的類是相同的,private和protected在外部不可見,protected和public在繼承類中可見。

  • 類的嵌套與包含是兩個不同的概念,類的包含是將向另一個類提供類對象,直接使用這個類,而類嵌套則不創建類成員,只是定義了一種類型。

  • 如果想在方法文件中定義構造函數而不是在h文件中,則需要使用兩次作用域解析運算符來完成。假設Node類是在Queue類中定義的,則在CPP文件中定義Node類的構造函數時,需要使用下面的語句:
Queue::Node::Node(){}

異常

1.使用abort()

  • abort()函數位於stdlib.h中,其實現大致是這樣的:向標準錯誤流cerr發送消息”abnormal program termination”消息之後直接終止程序,就相當於設定了一個特定輸出。

2.異常機制

  • C++異常指的是對程序運行過程中發生的異常情況的一種響應。異常提供了將控制權從程序的一個部分傳遞到另一個部分的途徑,一般來說有下面三個組成部分
    • 引發異常
    • 使用處理程序捕獲異常
    • 使用try塊
  • 這個異常處理的模板是按照下面的方式來進行的
try{
    //進行一系列判斷
    throw ...//這裏可以是任意的內容
}
catch(leixing1 x){//這裏的類型與前面throw後面直接加的類型是一致的
    //進行操作
}
catch(leixing2 x){//可以有多個catch語句來對應throw出來的不同類型的內容
    //進行操作
}
  • 下面是一個例子

    while(1)
    {
        cin>>k;
        try{
            if(k==-1)
                throw 1;
        }
        catch(int num){
            cout<<"throw"<<num<<endl;
            continue;
        }
    }
  • 如果不清楚異常的具體類型,則可以使用
catch(...){}//三個點就表示了對於任意類型的throw都可以進行處理

3.exception類

  • C++中提供了標準的異常類,需要#include<exception>,標準異常類爲exception,該類有個what函數,可以打印異常對象的異常信息。該what函數是虛函數,我們需要繼承exception類並重寫該what函數,在捕捉異常的時候,我們用父類的引用來接收自定義的標準異常類的子類對象(類型兼容性原則),然後打印該異常信息即可。
  • 它的catch語句可以如下面所寫
catch(exception &e){
    cout<<"throw"<<e.what()<<endl;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章