C++系列总结——封装
前言
众所周知,封装、继承和多态是面向对象编程的三大特性。C++作为一门面向对象的编程语言,自然支持了这些特性,但C++是如何实现这些特性的呢?今天先说下我理解的封装。
封装
通常我们会把下面的行为也叫封装,但面向对象的封装并不只是把函数或类型包裹在一起,更重要的是给这些函数或类型设置访问权限。
- 将一堆类型变量用一个结构体包裹起来,对外只有一个结构体名
- 将一堆过程用一个函数包裹起来,对外只有一个函数名
C++提供了三种权限
public:任何类都能可访问protected:只有本类或本类的派生类能访问private:只有本类能访问类指
class和struct,并不单指class。class和struct只有默认访问权限的区别
友元类和友元函数能访问该类的任何东西
访问权限只在编译阶段检查,而且检查的依据只是当前的类声明,举个例子来说明
- 执行
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++则提供了这种编程约束。
C++系列总结——封装的更多相关文章
- 架构漫谈系列(2) 封装(Encapsulation)
这是这个系列的第二篇.在第二篇里,我决定讲一讲封装. 程序的不同部分应该用封装去互相隔离,模块之间应该不应该产生很随意的关联. 可能有的人觉得不解,又或觉得是有道理的废话,不急,先一步一步来. 我们先 ...
- 3-STM32带你入坑系列(自己封装点亮一个灯的库--Keil)
2-STM32带你入坑系列(点亮一个灯--Keil) 首先建一个stm32f103x.h的文件,然后 #include "stm32f103x.h" 还记得上一节 现在呢就是做一个 ...
- jQuery组件系列:封装标签页(Tabs)
我自己封装的组件,你也行,静态链接地址 http://www.cnblogs.com/leee/p/5190489.html 声明.最好,先把代码拷过去运行一下,其实特别丑~再往下看 我没优化,因为我 ...
- <数据结构系列1>封装自己的数组——手写动态泛型数组(简化版ArrayList)
哈哈,距离上一次写博客已经快过去半个月了,这这这,好像有点慢啊,话不多说,开始我们的手写动态泛型数组 首先是我们自己写一个自己的动态数组类,代码如下所示: public class Array< ...
- javascript设计模式系列二-封装
JavaScript封装: var Book = function (id, name, price) { this.id = id, this.name = name, this.price = p ...
- JS组件系列——自己封装一个上传文件组件
页面调用: $('#fileUpload').cemsUpload({ errorEmpty:'<s:text name="cupgrade.view.tip.upload.file. ...
- 测试平台系列(80) 封装Redis客户端
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们编写了Redis ...
- openssl之EVP系列之1---算法封装
openssl之EVP系列之1---算法封装 ---依据openssl doc/crypto/EVP.pod翻译和自己的理解写成 (作者:DragonKing, Mail: wzhah ...
- 封装的多功能多效果的RecyclerView
开源界有一句很有名的话叫"不要重复发明轮子",当然,我今天的观点不是要反驳这句话,轮子理论给我们的开发带来了极大的便利,.但我想说的是,既要会用轮子,也要知道轮子怎么造,必要的时候 ...
随机推荐
- 【STM32H7教程】第5章 STM32H7下载和调试方法(MDK5)
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第5章 STM32H7下载和调试方法(MDK5) 本 ...
- C#读写EXCEL单元格的问题
最近, 我在用C#开发一个EXCEL Add-In的时候,发现了一些害人不浅的坑,特来总结列举如下: 这里我读写EXCEL引用的是using Excel = Microsoft.Office.Inte ...
- Asp.NetCore轻松学-部署到 Linux 进行托管
前言 上一篇文章介绍了如何将开发好的 Asp.Net Core 应用程序部署到 IIS,且学习了进程内托管和进程外托管的区别:接下来就要说说应用 Asp.Net Core 的特性(跨平台),将 .Ne ...
- Linux挖矿病毒 khugepageds详细解决步骤
一.背景 最近公司一台虚拟机被攻击,其中一种挖矿病毒.会伪CPU数.即如果用top命令只能看到一个cpu.并且负载不高.实际上整个负载300%以上,及时定时任务关掉也不起作用. 二.言归正传开始干掉这 ...
- Eureka注册客户端
1.pom.xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId ...
- 设计模式 | 观察者模式/发布-订阅模式(observer/publish-subscribe)
定义: 定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 结构:(书中图,侵删) 一个抽象的观察者接口, ...
- HTML 练习绑定onclick事件
方法一 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- java中强大的免费的集成开发环境(IDE)eclipse的使用技巧及注意事项
1调整字体,window->prefernce->Appereance->colors and fonts->Basic->Text font双击即可进行编辑 2.设置行 ...
- .NET 机器学习生态调查
机器学习是一种允许计算机使用现有数据预测未来行为.结果和趋势的数据科学方法. 使用机器学习,计算机可以在未显式编程的情况下进行学习.机器学习的预测可以使得应用和设备更智能. 在线购物时,机器学习基于历 ...
- Linux系统部署samba服务记录
Samba(Server Messages Block)是一种linux系统和windws系统之间依靠网络协议共享文件的服务程序,(Samba has provided secure, stable ...