1. 程式人生 > >清華大學《C++語言程式設計基礎》線上課程筆記03---資料的共享和保護&陣列

清華大學《C++語言程式設計基礎》線上課程筆記03---資料的共享和保護&陣列

資料的共享和保護

物件的生存期

static型別的區域性變數,生存期在整個程式,區域性可見。

void example()
{
    static a=1;
    int b=2
}
當呼叫完example函式後,b消亡,a仍然存在;
再次呼叫該函式時,a值不會再次被賦值,仍保持之前資料;而b需要重新建立,重新賦值。

類的靜態資料成員

1.用關鍵字static宣告;
2.為該類的所有物件共享,靜態資料成員具有靜態生存期;
3.必須在類外定義和初始化,用(::)來指明所屬的類.

這個資料屬於類的資訊,比如統計教師群體中教師的總數,即這個類例項化了多少個物件。

class A{
    static int num;   //在類內宣告
}

int A::num=0;  //在類外定義和初始化

類的靜態函式成員

1.類外程式碼可以使用類名和作用域操作符來呼叫靜態成員函式;
2.靜態成員函式主要用於處理該類的靜態資料成員,可以直接呼叫靜態成員函式;
3.如果訪問非靜態成員,要通過物件來訪問。

class A{
private:
    static int num;
    int a=1;
public:
   static void shownum(){cout<< num << endl;}   //2.
   static int change(int a);//一個定義的例子;
}
int A::num=0;
int A::change(int a){
    A::num=a;   //靜態資料成員的引用需要加 “類::”來修飾
}

int main(){
    A:shownum();    // 1.
}

類的友元

友元是C++提供的一種破壞資料封裝和資料隱藏的機制。

友元函式

在類宣告中由關鍵字friend修飾說明的非成員函式,在它的函式體中能
夠通過物件名訪問 private 和 protected成員

class Point { 
public:
    Point(int x=0, int y=0) : x(x), y(y) { }
    int getX() { return x; }
    int getY() { return y; }
    friend float dist(Point &a, Point &b);
private: 
    int x, y;
};

float dist( Point& a, Point& b) //非成員函式
{   double x = a.x - b.x;  //通過物件名訪問私有成員
    double y = a.y - b.y;return static_cast<float>(sqrt(x * x + y * y));
}

int main(){
    Point p1(1, 1), p2(4, 5);
    cout <<"The distance is: ";
    cout << dist(p1, p2) << endl; 
    return 0;
}

友元類

friend宣告是單向授權宣告,類A是類B的友元,意味著類A獲得了訪問類B的私有成員的許可權,但類B不能反向訪問類A的私有成員;

此處的friend更像是一種"上級宣告"
class A {
friend class B;
public:
void display() {cout << x << endl;}
private:
int x;
};

class B {
public:
void set(int i);
void display();
private:
A a; //B類中含有A類成員,正常來說是看不到封裝的私有成員的
};

void B::set(int i) {    a.x=i;  } //因為是友元,所以可以通過物件名訪問私有成員
void B::display() {     a.display();    }
共享資料的保護
  • 對於既需要共享、又需要防止改變的資料應該宣告為常型別(用const進行修飾);
  • 對於不改變物件狀態的成員函式應該宣告為常函式.

常型別

  • 常物件:必須進行初始化,不能被更新
    const 類名 物件名   const A a(1,2);
  • 常成員: 用const進行修飾的類成員:常資料成員和常函式成員
  • 常引用:被引用的物件不能被更新,既增加了效率又避免資料被篡改;常用作形參
const 型別說明符 &引用名  const int &p;const A &p;
  • 常陣列:陣列元素不能被更新(詳見第6章)。
型別說明符 const 陣列名[大小]...
  • 常指標:指向常量的指標(詳見第6章)。

    陣列

    處理無明顯規律的大量同類型資料時,可以通過將其存入陣列強制性新增一個次序資訊,再結合迴圈語句,對其進行處理。
a[10] 

陣列名 a 是一個地址(指標)型別常量,對應陣列首元素的記憶體地址,不能被賦值

陣列名作函式引數

  • 形、實引數都應是陣列名(實質上是地址),型別要一樣,傳送的是陣列首地址;
  • 對形引數組的改變會直接影響到實引數組.
void rowSum(int a[][4], int nRow) 
{
for (int i = 0; i < nRow; i++) 
{
    for(int j = 1; j < 4; j++)
        a[i][0] += a[i][j];
}
    
}

int table[3][4] = {{1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6}};
rowSum(table, 3); 

物件陣列

Point a[3];  

例項化3個Point類的物件,呼叫3次構造和3次解構函式;

基於範圍的for迴圈

  • 用來遍歷容器類十分方便
  • c++11標準
double prices[5]={4.99, 2.33, 5.86, 6.42, 4.51};
for (double x : prices)
      cout<<x<<std::endl;