衆所周知,封裝、繼承和多態是面向對象編程的三大特性。C++做爲一門面向對象的編程語言,天然支持了這些特性,但C++是如何實現這些特性的呢?今天先說下我理解的封裝。編程
一般咱們會把下面的行爲也叫封裝,但面向對象的封裝並不僅是把函數或類型包裹在一塊兒,更重要的是給這些函數或類型設置訪問權限。數據結構
C++提供了三種權限編程語言
public
:任何類都能可訪問protected
:只有本類或本類的派生類能訪問private
:只有本類能訪問函數
類指
class
和struct
,並不單指class
。class
和struct
只有默認訪問權限的區別
友元類和友元函數能訪問該類的任何東西code
訪問權限只在編譯階段檢查,並且檢查的依據只是當前的類聲明,舉個例子來講明對象
g++ student.cpp -fPIC -shared -o liba.so
將如下代碼編譯爲動態庫,提供給其餘人使用。// student.h class Student { public: Student(); private: int age; }; // student.cpp #include "student.h" Student::Student() { age = 10; }
student.h
,將全部成員變量的訪問權限都設爲public
class Student { public: Student(); int age; };
g++ main.cpp -L./ -la
編譯沒有報錯。——今後就能夠看出「權限檢查的依據只是當前的類聲明」// main.cpp #include "student.h" int main() { Student s; s.age = 40; // 肆意變動本身的年紀 return 0; }
固然能夠採用以下的方式來隱藏內部成員變量細節,這樣即便調用者修改了類聲明裏的訪問權限,也不知道爲了來達到本身的目的該如何修改。繼承
// student.h class Student { public: Student(); private: struct Internal; Internal* in; };
此外,這還帶來一個好處就是內部成員變量的修改,調用者徹底無感知,不須要更新頭文件了(我想這纔是使用這種方式的主要緣由)。固然這仍然沒法阻止別人猜想出數據結構後,直接使用成員變量地址去讀寫。我的以爲只有提供給第三方或第二方的類才須要使用這種方式(內部仍是能夠信任的)。若是全部類都這樣實現的話,可能就會致使內存碎片了。接口
我以爲封裝最大的意義仍是在於讓調用者不要關注本身無權訪問的內容(忽略細節),只須要基於本身可訪問的部分(基於接口)去實現業務。C是一門面向過程的語言,它是沒有訪問權限這一說的,調用者沒法知道哪些是本身無權訪問的,編譯器也沒法提醒越權訪問的錯誤,C++則提供了這種編程約束。內存