
一提到C++,大概很多人最先想到的就是類和對(duì)象這組概念。C++中的面向?qū)ο笏枷刖褪峭ㄟ^這組概念來實(shí)現(xiàn)的。面向?qū)ο蟮某绦蛟O(shè)計(jì)思想大家應(yīng)該并不陌生,在C語言的實(shí)踐項(xiàng)目中,我們已經(jīng)多次使用過了。不熟悉的同學(xué)可以去復(fù)習(xí)之前的文章。
這篇文章中,我們會(huì)針對(duì)一些C++中class常用的使用技巧進(jìn)行講解。雖然不會(huì)展開來講每一個(gè)細(xì)節(jié)用法,但希望能起到一個(gè)提綱挈領(lǐng)的效果。
1. 概念

1.1 類和對(duì)象的C++定義
剛接觸這組概念的時(shí)候,大部分人會(huì)混淆。今天我們嘗試用相對(duì)簡(jiǎn)單的方式去理解它們。C++中,我們把對(duì)象的數(shù)據(jù)類型稱為類。也就是說,所謂對(duì)象就是一種特殊的變量,這個(gè)變量的數(shù)據(jù)類型叫做類。與傳統(tǒng)數(shù)據(jù)類型不同,類是一種特殊的,可以自己設(shè)計(jì)的數(shù)據(jù)類型,它的功能更強(qiáng)大。
如圖所示,左邊是int型變量a,右邊是類A的對(duì)象a。從形式上講,是不是基本相同,只不過前者的數(shù)據(jù)類型不需要定義,而后者需要定義而已。
1.2 類和對(duì)象的邏輯關(guān)系
從邏輯上講,類是對(duì)象的抽象,而對(duì)象是類的具體實(shí)現(xiàn)。這句話幾乎困擾過所有學(xué)習(xí)面向?qū)ο蟮娜?。課堂上,老師總是用桌子和某一個(gè)桌子這樣的例子來說明類和對(duì)象的邏輯概念,效果并不太好。今天我告訴大家一個(gè)最簡(jiǎn)單的區(qū)分方法,我們把類和對(duì)象放在“什么是一個(gè)什么”這樣的句式中,如果成立,前面的就是對(duì)象,后面的就是這個(gè)對(duì)象的類型,也就是類。舉個(gè)例子,天花板和人,如果你分不清哪個(gè)是類哪個(gè)是對(duì)象的話就做下面的嘗試:
> 人是一個(gè)天花板
> 天花板是一個(gè)人
很容易分辨出第二句是符合邏輯的,那么天花板就是人的一個(gè)對(duì)象。是不是很容易?
當(dāng)你分清了類和對(duì)象的邏輯關(guān)系,下一步就是把這個(gè)關(guān)系和程序建立聯(lián)系。這需要在不斷的程序設(shè)計(jì)練習(xí)中慢慢摸索。
1.3 類和對(duì)象的物理關(guān)系
在物理結(jié)構(gòu)上,類是抽象的定義,不占用內(nèi)存空間,而每個(gè)對(duì)象是具體的,都會(huì)占用一段內(nèi)存空間。
2. 類的基本使用
類的使用分兩部分:聲明和使用。按照我的習(xí)慣,下面通過一段具體的代碼來講解它的用法。
#include <iostream>
#include <string>
using namespace std;
// Student類聲明
class Student
{
public:
Student()
{
m_id = 1;
m_name = "tianhuaban";
cout << "構(gòu)造函數(shù)" << endl;
}
Student(int id, string name) : m_id(id), m_name(name)
{
cout << "構(gòu)造函數(shù)1" << endl;
}
~Student()
{
cout << "析構(gòu)函數(shù) - " << m_name << endl;
}
void Display();
private:
int m_id;
string m_name;
};
void Student::Display()
{
cout << " id : " << m_id << endl;
cout << "name : " << m_name << endl;
}
// 類的使用
int main()
{
Student s1;
s1.Display();
Student s2(2, "abc");
s2.Display();
return 0;
}
上面這段代碼是一個(gè)類的基本使用方法,所有的教科書上都會(huì)有。如果你看不懂,那快去翻翻書,了解了基本的概念之后我們?cè)賮砝^續(xù)下面的內(nèi)容。
這段代碼的執(zhí)行結(jié)果如下:
接下來我們來看看有哪些需要特別注意的地方。
3. 類的內(nèi)容安排
可能有人注意到了,大部分課本都把private內(nèi)容寫在前面,而我建議大家把public內(nèi)容寫在前面。在面向?qū)ο蟮脑O(shè)計(jì)思想中,使用類的人最關(guān)心的是對(duì)外開放的部分,而不是私有內(nèi)容。因此,建議大家在安排類內(nèi)部的成員變量和成員函數(shù)時(shí),安裝public,protected、private這樣的先后順序,這個(gè)順序其實(shí)也是使用者關(guān)注的內(nèi)容順序。
另外,所有的成員變量都應(yīng)該定義為private,如果需要外部訪問,就添加一組成員函數(shù)來管理。比如,我們想在外部訪問學(xué)生id,可以加兩個(gè)成員函數(shù)。
void SetID(int id);
int GetID();
4. 構(gòu)造和析構(gòu)函數(shù)
構(gòu)造函數(shù)和析構(gòu)函數(shù)最大的特點(diǎn)是沒有返回值,前者是在對(duì)象被創(chuàng)建時(shí)自動(dòng)調(diào)用,后者是在對(duì)象被銷毀是自動(dòng)調(diào)用。我們的例子程序中,這兩個(gè)函數(shù)被調(diào)用時(shí)會(huì)打印出相應(yīng)的文字信息。
需要注意的是,被重載帶參數(shù)的構(gòu)造函數(shù)我們并沒有寫成下面這個(gè)樣子。
Student(int id, string name)
{
m_id = id;
m_name = name;
cout << "構(gòu)造函數(shù)1" << endl;
}
因?yàn)檫@兩種寫法的參數(shù)賦值時(shí)間是不同的,效率也有所差別,建議使用例子中的寫法。
構(gòu)造函數(shù)和析構(gòu)函數(shù)是一個(gè)對(duì)稱的存在,很容易讓我們聯(lián)想到代碼的對(duì)稱性。因此,關(guān)于成員變量的內(nèi)存空間生命周期管理應(yīng)該寫在這里。這一點(diǎn)今后我們還會(huì)涉及。
最后要注意的是構(gòu)造函數(shù)和析構(gòu)函數(shù)被調(diào)用的順序,原則是后構(gòu)造出的對(duì)象會(huì)先被掉用析構(gòu)函數(shù)。
5. 成員函數(shù)
例子中的Display函數(shù)的實(shí)現(xiàn)部分被寫在了函數(shù)的外邊。這其實(shí)是一種常規(guī)的寫法。在實(shí)際項(xiàng)目中,往往把類的聲明寫在.h文件中,而成員函數(shù)的實(shí)現(xiàn)寫在.cpp文件中,這樣對(duì)于類的使用者而言,只需要把精力集中在頭文件上就好了。
當(dāng)然,如果某些成員函數(shù)會(huì)被頻繁的調(diào)用,那么考慮到效率問題,可以像例子中的構(gòu)造函數(shù)那樣把實(shí)現(xiàn)部分直接寫在類的聲明中。
6. this指針

接下來我們介紹一些特殊用法。在類的對(duì)象中,有一個(gè)指向自己的指針this。
void Student::SetID(int id)
{
m_id = id;
}
void Student::SetID(int id)
{
this->m_id = id;
}
上面這兩種寫法的功能是完全相同的,使用this指針有兩個(gè)好處。
好處1
在VS等IDE中,輸入this->之后就會(huì)出現(xiàn)成員下拉列表,能夠方便選擇需要的成員變量或成員函數(shù),大大提高了編程效率。
好處2
當(dāng)成員變量名和參數(shù)名相同是,方便區(qū)分兩個(gè)變量。例如:
void Student::SetID(int m_id)
{
this->m_id = m_id;
}
上面這段代碼中,如果不寫this->編譯器將無法區(qū)分成員變量和形參。當(dāng)然,一般的代碼規(guī)范中是不允許出現(xiàn)成員變量和形參名相同這種情況的。
由于類和對(duì)象是貫穿在C++中的東西,這一篇中只介紹以上這些最基礎(chǔ)的。其他內(nèi)容會(huì)在后面的文章中深入講解。
我是天花板,讓我們一起在軟件開發(fā)中自我迭代。
如有任何問題,歡迎與我聯(lián)系。