標籤:屬性 操作方法 cte protect 方式 pre out empty 獨立
C++語言學習(三)——封裝(Encapsulation)一、封裝簡介
C語言等面向過程編程中,資料以及資料的相關操作函數都是分離的獨立個體;在C++等物件導向編程中,資料以及資料的相關操作被設計為對象,對象包括屬性(資料)和操作(函數),兩者共同構成對象實體(即類實體)。物件導向編程使程式更模組化,更易讀易寫,提升了代碼重用到一個更高的層次。
物件導向編程中,資料和資料的操作封裝為了對象。封裝可以隱藏實現細節,使得代碼模組化,是把過程和資料包圍起來,對資料的訪問只能通過已定義的介面。
封裝是一種對外提供服務的模型,封裝模型是對世間萬物的個體抽象。
封裝的訪問屬性如下:
訪問屬性 屬性 對象內部 對象外部
public 公有 可訪問 可訪問
protected 保護 可訪問 不可訪問
private 私人 可訪問 不可訪問
C語言中,struct中所有行為和屬性都是public的(預設),既可以使用介面,又可以直接存取其內部資料,沒有屏蔽內部資料。
C++語言中,強化了C語言的封裝特性,struct、class可以指定行為和屬性的訪問方式,對內開放資料,對外屏蔽資料,對外提供介面。
二、C語言的封裝
C語言中,通常使用模組化進行封裝。
stack的C語言實現:
#include <stdio.h>#include <string.h>typedef struct stack{ char space[1024]; int top;}stack;void stack_init(stack *st){ st->top = 0; memset(&st->space, 0, sizeof(st->space));}int is_empty(stack *st){ return st->top == 0;}int is_full(stack *st){ return st->top == 1024;}char pop(stack *st){ return st->space[--st->top];}void push(stack *st, char c){ st->space[st->top++] = c;}int main(void){ stack st; stack_init(&st); unsigned int i; for(i = ‘a‘; i < (‘z‘ + 1); i++) { if(!is_full(&st)) push(&st, i); } for(i = ‘a‘; i < (‘z‘ + 1); i++) { printf("%c\n", pop(&st)); } return 0;}
C語言中封裝的struct的資料成員是可以被外部調用修改的。
三、C++語言的封裝1、C++語言的封裝
C++語言強化了C語言的封裝,在類的標記法中定義了屬性和行為的存取層級。
C++語言中,用於表示類屬性的變數為成員變數;用於表示類行為的函數為成員函數。C++語言中,可以對類的成員變數和成員函數定義存取層級。
public:使用public關鍵字聲明的類的成員變數和成員函數可以在類的內部和外部存取與調用
private:使用private關鍵字聲明的類的成員變數和成員函數只能在類的內部訪問和調用
protected:使用protected關鍵字聲明的類的成員變數和成員函數只能在本類以及派生子類的內部訪問和調用。
類的成員的範圍只在類的內部,外部不能直接存取。類的成員函數可以直接存取成員變數和調用成員函數。類的外部可以通過類對象訪問public成員。
C++語言中,struct定義的類中成員的預設存取權限為public,class定義的類中成員的預設存取權限為private。
2、C++語言的struct
C++語言中,對struct關鍵字進行了擴充,struct已經不只是C語言中變數集合的struct,C++語言中的struct不僅可以定義成員函數,也可以實現繼承和多態。與C語言中的struct一樣,C++語言中使用struct定義類時,成員的預設存取層級為public。
#include <iostream>using namespace std;struct Person{ const char* name; int age; virtual void print() { printf("My name is %s, I‘m is %d years old.\n",name,age); }};//預設繼承存取權限為publicstruct Student : Person{ void print() { printf("My name is %s, I‘m is %d years old." "My score is %d\n",name,age,score); } void setScore(const int n) { score = n; }private: int score;};int main(int argc, char *argv[]){ Person p; p.name = "Bob"; p.age = 30; p.print(); Student s; s.name = "Bauer"; s.age = 20; s.setScore(98); s.print(); dynamic_cast<Person*>(&s)->print(); return 0;}
3、C++語言的class
由於C++語言的struct需要相容C語言的struct,C++語言使用新的class關鍵字定義類。使用class定義類時,成員的預設存取層級為private。
C++中的類支援聲明和實現的分離,將類的定義和實現分開,通常.h標頭檔中只有類的聲明,包括成員變數和成員函數的聲明;.cpp源檔案中完成類的成員函數的實現。
#include <iostream>using namespace std;class Person{public: const char* name; int age; virtual void print() { printf("My name is %s, I‘m is %d years old.\n",name,age); }};class Student : public Person{public: void print() { printf("My name is %s, I‘m is %d years old." "My score is %d\n",name,age,score); } void setScore(const int n) { score = n; }private: int score;};int main(int argc, char *argv[]){ Person p; p.name = "Bob"; p.age = 30; p.print(); Student s; s.name = "Bauer"; s.age = 20; s.setScore(98); s.print(); dynamic_cast<Person*>(&s)->print(); return 0;}
4、C++語言struct與class的區別
C++語言中struct與class最本質的區別如下:
A、預設存取權限不同。struct預設的存取權限是public的,class預設的存取權限是private的。
B、預設繼承存取權限不同。struct預設的繼承存取權限是public的,class預設的繼承存取權限是private的。
C、class可用作定義模板參數的關鍵字,而struct不可以。
C++語言中,繼承時如果沒有指定繼承存取權限,預設繼承存取權限是public繼承還是private繼承,取決於子類而不是基類。struct可以繼承class,class也可以繼承struct,預設的繼承存取權限取決於子類是struct還是class,如果子類使用struct聲明,預設繼承存取權限是public;如果子類使用class聲明,預設繼承存取權限是private。
#include <iostream>using namespace std;class Person{public: const char* name; int age; virtual void print() { printf("My name is %s, I‘m is %d years old.\n",name,age); }};//預設繼承存取權限為publicstruct Student : public Person{public: void print() { printf("My name is %s, I‘m is %d years old." "My score is %d\n",name,age,score); } void setScore(const int n) { score = n; }private: int score;};int main(int argc, char *argv[]){ Person p; p.name = "Bob"; p.age = 30; p.print(); Student s; s.name = "Bauer"; s.age = 20; s.setScore(98); s.print(); dynamic_cast<Person*>(&s)->print(); return 0;}
5、C++語言封裝樣本
C++類實現stack:
stack.h源碼:
#ifndef STACK_H#define STACK_Hclass stack{public: stack(); bool is_empty(); bool is_full(); void push(char c); char pop();private: char space[1024]; unsigned int top;};#endif // STACK_H
stack.cpp源碼:
#include "stack.h"#include <string.h>stack::stack(){ top = 0; memset(space, 0, sizeof(space));}bool stack::is_empty(){ return top == 0;}bool stack::is_full(){ return top == 1024;}void stack::push(char c){ space[top++] = c;}char stack::pop(){ return space[--top];}
main.cpp源碼:
#include <iostream>#include "stack.h"#include <string.h>using namespace std;int main(){ stack st; unsigned int i; for(i = ‘a‘; i < ‘z‘ + 1; i++) { if(!st.is_full()) st.push(i); } for(i = ‘a‘; i < ‘z‘ + 1; i++) { cout<<st.pop()<<endl; } return 0;}
C++語言中封裝的class stack中資料成員是private的,對於外部不可訪問,通過設定資料成員和操作方法的存取權限,可以對外部開放、屏蔽資料成員和操作方法。C++通過定義類成員的存取層級實現封裝機制。C++語言中類支援聲明和實現的分離,在標頭檔中聲明類,在源檔案中實作類別。
C++語言學習(三)——封裝(Encapsulation)