一、結構化程式設計與面向物件程式設計
1、結構化程式設計
- 在結構化程式設計中,采用自頂向下、逐步求精及模塊化的思想,將復雜的大問題層層分解為許多簡單的小問題,
- 在撰寫程式時,使用3種基本控制結構來構造程式,可以說,程式基本上都含有順序、選擇、回圈3種基本控制結構,這3種結構到目前為止仍是主要的控制結構,程式以控制結構為單位,只有一個入口和一個出口,基于控制結構可以從前往后地順序閱讀程式,程式的靜態描述與執行時的控制流程容易對應,所以可以獨立地理解各個部分,結構化程式設計主要強調的是程式的易讀性
2、面向物件程式設計的概念和特點
- 所謂面向物件的程式設計方法,就是使分析、設計和實作一個系統的方法盡可能地接近人們認識一個系統的方法,通常包括3個方面:面向物件的分析、面向物件的設計和面向物件的程式設計,
- 面向物件技術把問題看成是相互作用的事物的集合,也就是物件的集合,物件具有兩個特性:一是狀態;狀態是指物件本身的資訊,也稱為屬性;二是行為,行為是對物件的操作,通過對事物的抽象找出同一類物件的共同屬性(靜態特征)和行為(動態特征),從而得到類的概念,物件是類的一個具象,類是物件的一個抽象
3、面向物件的程式設計有“抽象”“封裝”“繼承”和“多型”4個基本特點,
- 抽象:物件是系統中用來描述客觀事物的一個物體,如各位員工是員工類的一個個物件,物件的特點包括兩個方面:屬性和操作,屬性指的是描述物件靜態特征的資料項,如員工的姓名、職位、薪水等,可以用變數來表示;操作指的是描述物件動態特征(即行為)的函式序列,也稱為方法或服務,如員工可以請假、加班,員工還可以獲得提拔、加薪等,C++中使用物件名、屬性和操作三要素來描述物件
- 封裝:在C++中,通過用戶定義的類來支持資料封裝和資訊隱藏,
- 繼承:在C++現有類的基礎上可以宣告新的類,將一個已有類中的資料和函式保留,并加上自己特殊的資料和函式,從而構成一個新類,這就是繼承和復用的思想,原來的類是基類,也稱為父類或超類,新類是派生類,也稱為子類,
- 多型:多型是指不同種類的物件都具有名稱相同的行為,而具體行為的實作方式卻有所不同,在一個類或多個類中,可以讓多個方法使用同一個名字,從而具有多型性,這是通過函式多載及運算子多載實作的多型,
二、類的定義
- 字母、數字和下劃線的組合,大小寫敏感,但不能以數字開頭,也不能和系統中使用的關鍵字完全相同,
- 類是具有唯一識別符號的物體,就是說類名不能重復,類定義以“;”結束,大括號中的部分稱為類體,
- 定義類時系統并不為類分配存盤空間,而只是把類看作是一種模板或樣板,或者說,類可以看作是用戶自定義的一種資料型別,在C++98標準下,類中宣告的任何成員不能使用auto、extern和register關鍵字進行修飾,
- 類中的成員按功能劃分,包括成員變數和成員函式;按訪問權限劃分,包括公有成員成、私有成員和保護員,
- 在C++中還可以定義不是任何類的成員的函式,這樣的函式可稱為“全域函式”
- 成員函式既可以在類體內定義,也可以在類體外定義,如果成員函式定義在類體內部,則默認是行內函式,也可以在類體內部宣告函式,并加上inline關鍵字,然后在類體外給出函式定義,這樣的成員函式也是行內函式,
- 如果成員函式定義在類體外,則類體內必須要有函式原型,類體外函式定義的前面必須用“類名::”來限定,格式如下:
-
回傳值型別 類名::成員函式名(引數串列){ 成員函式的函式體 } - 類名是成員函式所屬類的名字,符號::是類作用域運算子,表明它后面的成員函式是屬于類名標識的這個類的,回傳值型別就是這個成員函式回傳值的型別,
- 類C中不能定義類C的成員變數,但可以定義類C的指標和參考,
- 成員函式并非每個物件各自存有一份,成員函式和普通函式一樣,在記憶體中只有一份,它可以作用于不同的物件,為類中各物件共享,
- 通常,因為函式體代碼較長,所以在類體內僅給出成員函式的原型,然后在類體外給出對應的函式體,如果函式體定義在類體內,則系統將其視為行內函式,類中定義的成員函式允許多載,


三、C++程式結構
一個完整的C++程式包括以下幾部分:
- ? —個主函式,可以呼叫其他函式,但不能被呼叫,也稱為主程式,
- ? 用戶定義的任意多個的類及全域函式,
- ? 全域說明,在所有函式和類定義之外的變數說明及函式原型,
- ? 注釋,
- ? 頭檔案,
- 對于比較大的程式,根據主函式和各用戶定義的類及全域函式的功能及相互關系,可以把類及全域函式劃分為幾個程式檔案,包括.cpp檔案和.h檔案,.cpp檔案是源程式檔案,.h檔案是頭檔案,
- 從邏輯關系上看,典型的C++程式的結構包括類的定義、類中成員函式的實作及主函式main,
四、Class 中的訪問權限
- public(公有的): 使用它修飾的類的成員可以在程式的任何地方被訪問,
- private(私有的): 使用它修飾的類的成員僅能在本類內被訪問,
- protected(保護的): 它的作用介于public與private之間,使用它修飾的類的成員能在本類內及子類中被訪問,
- 私有型別的成員在類外是不能訪問的,通過公有函式訪問的效率比直接訪問的效率要低,為了權衡這兩方面的因素,C++提供了友元訪問方式,只有在類內和在友元函式內才可以訪問私有成員,
五、Class 的使用
1、建構式
- 為了對物件進行初始化,C++提供了一種稱為建構式的機制,用于對物件進行初始化,實際上是用來為成員變數賦初值的,
- 建構式是類中的特殊成員函式,它屬于類的一部分,給出類定義時,由程式員撰寫建構式,如果程式員沒有撰寫類的任何建構式,則由系統自動添加一個不帶引數的建構式,
- 宣告物件后,可以使用new運算子為物件進行初始化,此時呼叫的是物件所屬類的建構式,建構式的作用是完成物件的初始化作業,用來保證物件的初始狀態是確定的,在物件生成時,系統自動呼叫建構式,用戶在程式中不會直接呼叫建構式,
- 定義一個類時,需要為類定義相應的建構式,建構式的函式名與類名相同,沒有回傳值,一個類的建構式可以有多個,即建構式允許多載,同一個類的多個建構式的引數表一定不能完全相同,
- 當類中沒有定義任何建構式時,系統會自動添加一個引數表為空、函式體也為空的建構式,稱為默認建構式,所以任何類都可以保證至少有一個建構式,如果程式員在程式中已經定義了建構式,則系統不會再添加默認建構式,
- 在宣告類的建構式時可以同時給出函式體,這樣的建構式稱為行內建構式,也可以在類體外給出建構式的定義,建構式的宣告中,形參的個數可以為0,即引數表為空
建構式的格式:
建構式的宣告格式如下:類名(形參1, 形參2, …,形參n) 在類體外定義建構式時通常有三種形式 //形式一: 類名::類名(形參1,形參2,…,形參n):x1(形參1), x2(形參2), …, xn(形參n){} //形式二: 類名::類名(形參1,形參2,…,形參n){ x1=形參1; x2=形參2; …… xn=形參n; } //形式三: 類名::類名(){ x1=初始化運算式1; x2=初始化運算式2; …… xn=初始化運算式n; }
初始化時機:定義類的成員函式、成員物件及友元函式時,均不呼叫類的建構式,僅當定義類的物件時,才由系統自動呼叫類的建構式
建構式的使用:
- C++語言規定,創建類的任何物件時都一定會呼叫建構式進行初始化,物件需要占據記憶體空間,生成物件時,為物件分配的這段記憶體空間的初始化由建構式完成,
- 陣列:特別地,如果程式中宣告了物件陣列,即陣列的每個元素都是一個物件,則一定要為物件所屬的這個類定義一個無參的建構式,因為陣列中每個元素都需要呼叫無參的建構式進行初始化,所以必須要有一個不帶引數的建構式,
class Person{ private: int id; string name; public: Person(); Person(int id,string name); ~Person(); void setName(string name); string getName(); void setId(int id); int getId(); static void print(Person *person){ cout<< "id:" << person->id << " name:" << person->name <<endl; delete person; } }; Person::Person(){ cout<<"無慘建構式" <<endl; } Person::Person(int id,string name){ this->id=id; this->name=name; cout << "有2個引數的建構式" <<endl; } int main(){ Person pe(); Person pe2=Person(1,"張三"); }
1、使用new關鍵字
用new創建物件時回傳的是一個物件指標,這個指標指向本類剛創建的這個物件,C++分配給指標的僅僅是存盤指標值的空間,而物件所占用的空間分配在堆上,使用new創建的物件,必須用delete來撤銷,
//4、類名 *物件指標名 = new 類名; Student *stu4=new Student(3,'D'); cout<< stu4->getName() <<endl;
類名 &物件參考名 = 物件;
Student stu3=Student(3,'C'); Student &str4=stu3; cout << str4.getName()<<endl;
類名 *物件指標名 = 物件的地址;
Student stu3=Student(3,'C'); Student *str4=&stu3; cout << str4->getName()<<endl;
類名 物件陣列名[陣列大小];
Student stu3[10]; Student stu4=Student(3,'C'); stu3[0]=stu4;
同型別的物件之間可以相互賦值,物件和物件指標都可以用作函式引數,函式的回傳值可以是物件或指向物件的指標,
2、 復制建構式(拷貝建構式):
復制建構式是建構式的一種,也稱為拷貝建構式,它的作用是使用一個已存在的物件去初始化另一個正在創建的物件,例如,類物件間的賦值是由復制建構式實作的,
復制建構式只有一個引數,引數型別是本類的參考,復制建構式的引數可以是const參考,也可以是非const參考,一個類中可以寫兩個復制建構式,一個函式的引數是const參考,另一個函式的引數是非const參考,這樣,當呼叫復制建構式時,既能以常量物件(初始化后值不能改變的物件)作為引數,也能以非常量物件作為引數去初始化其他物件,
復制建構式的原型如下:
- 格式一 A::A(const A&)
- 格式二 A::A(A &)
自動呼叫復制建構式的情況有以下3種:
1)當用一個物件去初始化本類的另一個物件時,會呼叫復制建構式,例如,使用下列形式的說明陳述句時,即會呼叫復制建構式,
- 類名 物件名2(物件名1);
- 類名 物件名2=物件名1;
2)如果函式F的引數是類A的物件,那么當呼叫F時,會呼叫類A的復制建構式,換句話說,作為形參的物件,是用復制建構式初始化的,而且呼叫復制建構式時的引數,就是呼叫函式時所給的實參,
3)如果函式的回傳值是類A的物件,那么當函式回傳時,會呼叫類A的復制建構式,也就是說,作為函式回傳值的物件是用復制建構式初始化的,而呼叫復制建構式時的實參,就是retrun陳述句所回傳的物件,
注意,在復制建構式的引數表中,加上const是更好的做法,這樣復制建構式才能接收常量物件作為引數,即才能以常量物件作為引數去初始化別的物件,
class Person{ public: Person(const Person &person); Person(Person &person); } Person::Person(const Person &person){ cout << "const型別 copy 建構式" << endl; } Person::Person(Person &person){ this->id=person.id; this->name=person.name; cout << "copy 建構式" << endl; }

3、解構式:
- 與建構式一樣,解構式也是成員函式的一種,它的名字也與類名相同,但要在類名前面加一個“~”字符,以區別于建構式,解構式沒有引數,也沒有回傳值,一個類中有且僅有一個解構式,如果程式中沒有定義解構式,則編譯器自動生成默認的解構式,解構式不可以多于一個,不會有多載的解構式,默認解構式的函式體為空,
- 創建物件時自動呼叫建構式,那么,什么時候呼叫解構式呢?可想而知,在物件消亡時自動呼叫解構式,解構式的作用是做一些善后處理的作業,例如,如果在創建物件時使用new運算子動態分配了記憶體空間,則在解構式中應該使用delete釋放掉這部分占用的空間,保證空間可再利用,
- 當使用new運算子生成物件指標時,自動呼叫本類的建構式,使用delete洗掉這個物件時,首先為這個動態物件呼叫本類的解構式,然后再釋放這個動態物件占用的記憶體,
- 如果是創建普通物件:Person p();則無需使用delete p釋放否空間,他在程式結束的時候會自動呼叫解構式
class Person{ public: ~Person(); } Person::~Person(){ cout<< "解構式" << endl; }
對于物件陣列,要為它的每個元素呼叫一次建構式和解構式,全域物件陣列的解構式在程式結束之前被呼叫,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/24328.html
標籤:C++
上一篇:C++ 名稱空間
