众所周知,封装、继承和多态是面向对象编程的三大特性。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++则提供了这种编程约束。内存