Chapter 5.4 類別與函數 - TKU-ME-Lab/C-C-_tutorial GitHub Wiki

<1>const物件函數

1.const用來宣告物件為常數物件,而宣告常數物件的方式與宣告一般常數變數的方法相同
2.常數物件表示該物件中資料成員與成員函數皆為固定,所以該物件中的資料成員與成員函數值是不可被更改的
3.常數型態物件不能呼叫物件中非常數型態的成員函數,但可以再定義一個相同名稱與功能的常數型態成員函式,提供常數型態物件呼叫用

const 類別名稱 物件名稱(參數列);


class Employee
{
     int EmpId;   
     char name[20];   
public:
     Employee(int e,char n[])   
     {
         EmpId = e;
         strcpy_s(name,n);
     }
     void outputEmp()
     {
          cout << this->EmpId << endl;   //取得Employee指標的EmpId
          cout << (*this).name << endl;   //取得Employee指標的name
     }
};
int main()
{
     const Employee emp1(123,"JERRY");   //為常數物件
     emp1.outputEmp();   //錯誤,Non-const function call
     system("pause");
     return 0;
}
//定義一個常數物件emp1,起始值為emp.EmpId=123,emp1.name="JERRY"
但因為emp1是常數物件,所以不能呼叫非常數成員函數emp1.outputEmp()

<2>const物件函數

1.指定一個函數為常數函數,必須在宣告函數原型與定義函數本體時,在參數列之後將上const
2.常數型態的成員函數內部的敘述不能改變資料成員的值,也不能呼叫非常數型態的成員函數
3.建構子與解構子不能被宣告為常數型態

函數型態 函數名稱(參數列) const
{
     //函數本體
}


Example1:

class Employee
{
     int EmpId;   
     char name[20];   
public:
     Employee(int e,char n[])   
     {
         EmpId = e;
         strcpy_s(name,n);
     }
     void outputEmp()
     {
          cout << this->EmpId << endl;   
          cout << (*this).name << endl;   
     }
};
int main()
{
     Employee emp1(123,"JERRY");   
     emp1.outputEmp();   
     system("pause");
     return 0;
}    
//定義一個常數物件emp1,起始值為emp.EmpId=123,emp1.name="JERRY"
然後呼叫常數成員函數emp1.outputEmp()輸出資料


Example2:

#include<iostream>
#include<iomanip>
using namespace std;

class Employee
{
     int EmpId;   
     char name[20];   
public:
     void inputEmp();
     void outputEmp() const;
};   //宣告常數函數原型
void Employee::inputEmp()
{
     cout << "EmpId:";
     cin >> EmpId;
     cout << "EmpName:";
     cin >> name;
}
void Employee::outputEmp() const
{
     cout << EmpId << '\t';
     cout << name << endl;
}
int main()
{
     Employee emp1;
     emp1.inputEmp();
     cout << "\nID\tEmpName\n";
     cout << "--\t-------\n";
     emp1.outputEmp();
     system("pause");
     return 0;
}    

friend函數與類別

1.Friend函數必須在宣告函數原型與定義函數本體時,在前面加上friend關鍵字
2.雖然friend函數定義於類別中,但仍然不是該類別的成員函式.因此friend函式可以被宣告於類別的任何存取型態(public,private,protected)區域中,而且friend函數可以存取該類別的private成員
3.friend函數通常宣告於類別之後,而且不限定任何存取區域(public,private,protected)

friend 函數型態 函數名稱(參數列){敘述區;}

若類別A是類別B的friend,則類別A中所有的函數皆為類別B的friend函數,且類別A中所有函數皆可存取類別B的所有成員.定義類別A為B的friend類別,是在類別B中加入friend class A

class 類別B
{
     friend class 類別A;
}


Example1:

class First
{
     int x;
public:
     friend int getx(First obj)   //定義friend函數
     {
          return obj.x;
     }
};
class Second
{
     int y;
public:
     void showxy(First obj)
     {
          cout << "x=" << getx(obj) << endl;
          cout << "y=" << y << endl;
     }
};
//在First類別中,宣告getx()函數為friend函數,所以getx()不屬於First類別的成員函式
因此在second類別中,showxy()成員函數才可以呼叫getx()函數


Example2:

#include<iostream>
using namespace std;

class First
{
     int x;
public:
     void setx(int var)
     {
          x = var;
     }
     friend int getx(First obj)   
     {
          return obj.x;
     }
};    
class Second
{
     int y;
public:
     void sety(int var)
     {
          y = var;
     }
     void showxy(First obj)
     {
          cout << "x=" << getx(obj) << endl;
          cout << "y=" << y << endl;
     }
};
int main()
{
     First A;
     Second B;
     A.setx(10);
     B.sety(20);
     B.showxy(A);
     system("pause");
     return 0;
}          

static類別成員

1.在類別中static也可用來宣告靜態類別成員,宣告時只要在類別成員前面加上static關鍵字即可
2.static成員函數沒有this指標.靜態成員的資料將被保留直到下一次資料跟新或程式結束
3.若某個成員函數被宣告為static,則該成員函數不可呼叫非static成員函數.因為static資料成員和static成員函數與類別中其他成員無關

static 資料型態 變數名稱;

static 函數型態 函數名稱(參數列){敘述區;}


class Oddsum
{
     static int sum;
public:
     static void addition(int n);
};

int Oddsum::sum = 0;    
 
void Oddsum::addition(int n)
{
     sum += n;
}
int main()
{
     Oddsum A;
     for (int count = 1;count <= 100;count += 2)
     {
          A.addition(count);
     }
     system("pause");
     return 0;
}   //宣告靜態資料成員與成員函數
//在檔案中靜態資料成員必須被起始一次,而且也只能被起始一次,如範例中 int Oddsum::sum = 0
⚠️ **GitHub.com Fallback** ⚠️