1.類成員的可訪問范圍
- private: 私有成員首妖,只能在成員函數(shù)內(nèi)訪問
- public : 公有成員铐望,可以在任何地方訪問
- protected: 保護(hù)成員,以后再說
class className {
private:
私有屬性和函數(shù)
public:
公有屬性和函數(shù)
protected:
保護(hù)屬性和函數(shù)
};
如過某個(gè)成員前面沒有上述關(guān)鍵字,則
- 在類的成員函數(shù)內(nèi)部渗蟹,能夠訪問:
-當(dāng)前對(duì)象的全部屬性贮尉,函數(shù)
-同類其他對(duì)象的全部屬性拌滋、函數(shù) - 在類的成員函數(shù)以外的地方,只能夠訪問該類對(duì)象的公有成員猜谚。
-
設(shè)置私有成員的機(jī)制败砂,叫隱藏
隱藏”的目的是強(qiáng)制對(duì)成員變量的訪問一定要通過成員函數(shù)進(jìn)行赌渣,那么以后成員變量的類型等屬性修改后,只需要更改成員函數(shù)即可昌犹。否則坚芜,所有直接訪問成員變量的語句都需要修改。
2.成員函數(shù)的重載及參數(shù)缺省
- 成員函數(shù)也可以重載
- 成員函數(shù)可以帶缺省參數(shù)
使用缺省參數(shù)要注意避免有函數(shù)重載時(shí)的二義性
#include <iostream>
using namespace std;
class Location {
private:
int x, y;
public:
void init(int x = 0, int y = 0);
void valueX(int val) { x = val; }
int valueX() { return x; }
};
void Location::init(int X, int Y)
{
x = X;
y = Y;
}
int main() {
Location A, B;
A.init(5);
A.valueX(5);
cout << A.valueX(); //5
return 0;
}
3.構(gòu)造函數(shù)
- 基本概念:
成員函數(shù)的一種
? 名字與類名相同斜姥,可以有參數(shù)鸿竖,不能有返回值(void也不行)
? 作用是對(duì)對(duì)象進(jìn)行初始化,如給成員變量賦初值
? 如果定義類時(shí)沒寫構(gòu)造函數(shù)铸敏,則編譯器生成一個(gè)默認(rèn)的無參數(shù)
的構(gòu)造函數(shù)
?默認(rèn)構(gòu)造函數(shù)無參數(shù)缚忧,不做任何操作
? 如果定義了構(gòu)造函數(shù),則編譯器不生成默認(rèn)的無參數(shù)的構(gòu)造函數(shù)
? 對(duì)象生成時(shí)構(gòu)造函數(shù)自動(dòng)被調(diào)用杈笔。對(duì)象一旦生成闪水,就再也不能在
其上執(zhí)行構(gòu)造函數(shù)
?一個(gè)類可以有多個(gè)構(gòu)造函數(shù)
- 為什么需要構(gòu)造函數(shù):
- 構(gòu)造函數(shù)執(zhí)行必要的初始化工作,有了構(gòu)造函數(shù)桩撮,就不
必專門再寫初始化函數(shù)敦第,也不用擔(dān)心忘記調(diào)用初始化函數(shù)。 - 有時(shí)對(duì)象沒被初始化就使用店量,會(huì)導(dǎo)致程序出錯(cuò)芜果。
3)構(gòu)造函數(shù)最好是public的,private構(gòu)造函數(shù)不能直接用來初始化對(duì)象
4.構(gòu)造函數(shù)在數(shù)組中的使用
class CSample {
int x;
public:
CSample() {
cout << "Constructor 1 Called" << endl;
}
CSample(int n) {
x = n;
cout << "Constructor 2 Called" << endl;
}
};
int main() {
CSample array1[2];
cout << "step1" << endl;
CSample array2[2] = { 4,5 };
cout << "step2" << endl;
CSample array3[2] = { 3 };
cout << "step3" << endl;
CSample * array4 =
new CSample[2];
delete[]array4;
return 0;
/*
Constructor 1 Called
Constructor 1 Called
step1
Constructor 2 Called
Constructor 2 Called
step2
Constructor 2 Called
Constructor 1 Called
step3
Constructor 1 Called
Constructor 1 Called
*/
}
class Test {
public:
Test(int n) { } //(1)
Test(int n, int m) { } //(2)
Test() { } //(3)
};
Test array1[3] = { 1, Test(1,2) };
// 三個(gè)元素分別用(1),(2),(3)初始化
Test array2[3] = { Test(2,3), Test(1,2) , 1 };
// 三個(gè)元素分別用(2),(2),(1)初始化
Test * pArray[3] = { new Test(4), new Test(1,2) };
//兩個(gè)元素分別用(1),(2) 初始化
5.復(fù)制構(gòu)造函數(shù)
- 基本概念
? 只有一個(gè)參數(shù),即對(duì)同類對(duì)象的引用融师。
? 形如 X::X( X& )或X::X(const X &), 二者選一
后者能以常量對(duì)象作為參數(shù)
? 如果沒有定義復(fù)制構(gòu)造函數(shù)右钾,那么編譯器生成默認(rèn)
復(fù)制構(gòu)造函數(shù)。默認(rèn)的復(fù)制構(gòu)造函數(shù)完成復(fù)制功能旱爆。 - 復(fù)制構(gòu)造函數(shù)起作用的三種情況:
- 當(dāng)用一個(gè)對(duì)象去初始化同類的另一個(gè)對(duì)象時(shí)舀射。
Complex c2(c1);
Complex c2 = c1; //初始化語句,非賦值語句
- 如果某函數(shù)有一個(gè)參數(shù)是類 A 的對(duì)象怀伦,
那么該函數(shù)被調(diào)用時(shí)脆烟,類A的復(fù)制構(gòu)造函數(shù)將被調(diào)用。
class A
{
public:
A() { };
A(A & a) {
cout << "Copy constructor called" << endl;
}
};
void Func(A a1) { }
int main() {
A a2;
Func(a2);
return 0;
}
- 如果函數(shù)的返回值是類A的對(duì)象時(shí)房待,則函數(shù)返回時(shí)邢羔,A的復(fù)制構(gòu)造函數(shù)被調(diào)用:
class A
{
public:
int v;
A(int n) { v = n; };
A(const A & a) {
v = a.v;
cout << "Copy constructor called" << endl;
}
};
A Func() {
A b(4);
return b;
}
int main() {
cout << Func().v << endl; return 0;
}
6.類型轉(zhuǎn)換構(gòu)造函數(shù)
? 定義轉(zhuǎn)換構(gòu)造函數(shù)的目的是實(shí)現(xiàn)類型的自動(dòng)轉(zhuǎn)換。
? 只有一個(gè)參數(shù)桑孩,而且不是復(fù)制構(gòu)造函數(shù)的構(gòu)造函數(shù)拜鹤,一般就可以看作是轉(zhuǎn)換構(gòu)造函數(shù)毅桃。
? 當(dāng)需要的時(shí)候饶唤,編譯系統(tǒng)會(huì)自動(dòng)調(diào)用轉(zhuǎn)換構(gòu)造函數(shù),建立一個(gè)無名的臨時(shí)對(duì)象(或臨時(shí)變量)洼冻。
class Complex {
public:
double real, imag;
Complex(int i) {//類型轉(zhuǎn)換構(gòu)造函數(shù)
cout << "IntConstructor called" << endl;
real = i; imag = 0;
}
Complex(double r, double i) { real = r; imag = i; }
};
int main()
{
Complex c1(7, 8);
Complex c2 = 12;
c1 = 9; // 9被自動(dòng)轉(zhuǎn)換成一個(gè)臨時(shí)Complex對(duì)象
cout << c1.real << "," << c1.imag << endl;
return 0;
}
class Complex {
public:
double real, imag;
explicit Complex(int i) {//顯式類型轉(zhuǎn)換構(gòu)造函數(shù)
cout << "IntConstructor called" << endl;
real = i; imag = 0;
}
Complex(double r, double i) { real = r; imag = i; }
};
int main() {
Complex c1(7, 8);
Complex c2 = Complex(12);
c1 = 9; // error, 9不能被自動(dòng)轉(zhuǎn)換成一個(gè)臨時(shí)Complex對(duì)象
c1 = Complex(9) //ok
cout << c1.real << "," << c1.imag << endl;
return 0;
}
7.析構(gòu)函數(shù)
- 名字與類名相同,在前面加‘~’ 惯裕, 沒有參數(shù)和返回值温数,一個(gè)類最多只能有一個(gè)析構(gòu)函數(shù)。
- 析構(gòu)函數(shù)對(duì)象消亡時(shí)即自動(dòng)被調(diào)用轻猖》牵可以定義析構(gòu)函數(shù)來在
對(duì)象消亡前做善后工作,比如釋放分配的空間等咙边。 - 如果定義類時(shí)沒寫析構(gòu)函數(shù)猜煮,則編譯器生成缺省析構(gòu)函數(shù)。缺省析構(gòu)函數(shù)什么也不做败许。
- 如果定義了析構(gòu)函數(shù)王带,則編譯器不生成缺省析構(gòu)函數(shù)。
- 對(duì)象數(shù)組生命期結(jié)束時(shí)市殷,對(duì)象數(shù)組的每個(gè)元素的析構(gòu)函數(shù)都會(huì)被調(diào)用愕撰。
- 若new一個(gè)對(duì)象數(shù)組,那么用delete釋放時(shí)應(yīng)該寫[].否則只delete一個(gè)對(duì)象(調(diào)用一次析構(gòu)函數(shù))