Chapter 5.4 類別與函數 - TKU-ME-Lab/C-C-_tutorial GitHub Wiki
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()
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;
}
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;
}
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