c++类的编程规范
2015-09-11 22:29
543 查看
类是c++中必不可少的一部分,类是面向对象(oo)的基础,是一个非常强大的功能,也是c++中最容易被滥用的功能之一。
类是应面向对象而诞生的,而过度并且无脑的面向对象,使程序大幅度的包装,无谓的抽象,以及本身对类的使用不规范,导致了大量无谓低效的代码诞生,本章讲解的就是博主对类的使用的一点理解。
1.明确类的意义
类,指的就是一群,一个group,类是许多具有同一个性的物体的整体抽象,桌子,椅子都是一个类,家具类,电视电脑都是一个类,电子物品类,一个类是一个群体,而不是一个单独的部件,一个只能是指代单个物品的类已经不是类了,而是一种特化。
所以,如果对于我们最熟悉的电脑,我们想要设计一个类去表现他,改怎么做?
首先,合理的使用面向对象的思维是关键,面向对象是符合实际的编程,而在实际生活中电脑是什么样的?一个电脑是由各种东西“组成”的,对,组成,而非继承,cpu,
显卡,内存等一系列部件通过内部组装成就了我们的电脑,然后这一切在我们脑子里构成了最初的代码,我们不构建任何类作为computer的基类,假若你选择先构建一堆类,代表cpu,memory,然后将他们通过继承生成一个新类并将其命名为computer,或许最终能拿到一个不错的computer类,但是思想却已经偏离现实了
2.寻找通性
可是这还不够,电脑是一个类,一个满足封装性的类具有很多的private 成员,但依旧需要许多的public成员,而电脑是怎样映射c++中的类的?一个很好的例子就是鼠标,键盘,显示屏以及USB插口,电脑依靠这些接口与别的东西交互,这一典型关系映射了面向对象编程封装与接口的原则,我们可以这样更改我们的程序,先建立大致交互的接口
然后我们继续思考,怎样构建我们的私有成员,也就是我们电脑外壳下面的各式部件,或许急于编程的新手会这么做,为每一个部件构建一个类,然后将他们放置与computer下,就像这样子
我们暂时不管构造函数的与其他东西的实现(事实上,一个好的类库,仅仅依靠接口以及一定的注释就能让使用者明白这个东西)但是,这违反了类的一个原则,代表一类事物,类,是一类事物的抽象,对于具体的事物我们可以对其进行特化,但不应该直接将其定位一类,在这里,不是一类了,而是一个。所以,我们要对cpu,memory等进行一个抽象,他们在计算机中的共同之处是什么?对,有一个我们反复强调的词,部件,component,电脑由多个component所构成,cpu是一个,memory是一个,包括鼠标,键盘也是一个,所以我们构建一个新的类,component,他将包含每个部件都应该有的一些东西,或者还有一些纯虚函数
,更改我们的代码到如下形态
而在这之后,我们才可以进行类的特化,所谓类的特化,就是通过继承的方式,把对某一大类的抽象的基类细化为针对某一明确类型的东西,如之前所说的,有些人可能以上来直接建立一个针对某一对象的类,有时候,在一些比较特殊或比较简单的时候,的确可以这样做,但是,在一个比较大而复杂的环境中,明确的继承,基于抽象的细化会获得更好的效果,也更易于理解和更改,基础的方式也易于实现基于虚函数的多态实现,我们再次更改我们的代码,通过继承新建三个类,再一次更改我们的computer类
这就是一个比较好的实现,继承公有属性并拥有特殊能力的部件通过组合得到了电脑,外加虚函数的使用可以让这些部件适应给多的接口,还有一点,劲量将简单的接口暴露给别的个体,这在具有多个类的时候实现松耦合非常重要,类与类之间,商定了通讯协议后绝对不能通过某种方法,使数据通过非公有函数,非正常渠道传递,否则的话后果就是函数的高度耦合,高度耦合会给两边类带来灾难性的后果,依旧是计算机这个例子,我们将其映射到真实世界中,用面向对象思维做一点对比。
人用计算机,这是双边关系,我们将其作为两个类,人对计算机通讯依靠是鼠标与键盘的事件,USB,计算机对人的通讯依靠显示器,如果有一方失效了,另一方不会有任何损失,计算机的键盘失效了,我们依旧敲,然后从显示屏上得到的数据判断出有问题,我们不敲了,可以喝杯咖啡,人什么问题都没有,鼠标也一样;而人有问题了,乱敲键盘,计算机依旧正常响应他能响应的命令,这就是低耦合,一边出问题对别的类影响并不大,而高耦合是什么呢?
我们幻想一个疯狂的情形,我们把计算机的键盘给扯了,直接使用内部的电路对电脑操作,也就是说,我们通过了某种非常不可理喻的方法直接通过private成员操作了数据,然后我们应为某些原因间歇性的发疯,拿起操起一把刀往电脑电路一顿砍,没有了外壳的保护,内部电路被疯狂的我们轻易的砍的一塌糊涂(这只是个比喻,现在的电脑能不能抗住刀砍还真没试过),然后电脑炸了,电火花把人也给炸了,很疯狂,不是么,但是我相信很多人面对一个由十几个,几十个高度耦合的类组成的项目时,真的会有那刀砍电脑的冲动,当然了,是这个项目作者的电脑
类是应面向对象而诞生的,而过度并且无脑的面向对象,使程序大幅度的包装,无谓的抽象,以及本身对类的使用不规范,导致了大量无谓低效的代码诞生,本章讲解的就是博主对类的使用的一点理解。
1.明确类的意义
类,指的就是一群,一个group,类是许多具有同一个性的物体的整体抽象,桌子,椅子都是一个类,家具类,电视电脑都是一个类,电子物品类,一个类是一个群体,而不是一个单独的部件,一个只能是指代单个物品的类已经不是类了,而是一种特化。
所以,如果对于我们最熟悉的电脑,我们想要设计一个类去表现他,改怎么做?
首先,合理的使用面向对象的思维是关键,面向对象是符合实际的编程,而在实际生活中电脑是什么样的?一个电脑是由各种东西“组成”的,对,组成,而非继承,cpu,
显卡,内存等一系列部件通过内部组装成就了我们的电脑,然后这一切在我们脑子里构成了最初的代码,我们不构建任何类作为computer的基类,假若你选择先构建一堆类,代表cpu,memory,然后将他们通过继承生成一个新类并将其命名为computer,或许最终能拿到一个不错的computer类,但是思想却已经偏离现实了
class Computer { private: //something like cpu ,video card,memory... };
2.寻找通性
可是这还不够,电脑是一个类,一个满足封装性的类具有很多的private 成员,但依旧需要许多的public成员,而电脑是怎样映射c++中的类的?一个很好的例子就是鼠标,键盘,显示屏以及USB插口,电脑依靠这些接口与别的东西交互,这一典型关系映射了面向对象编程封装与接口的原则,我们可以这样更改我们的程序,先建立大致交互的接口
class Computer { public: int keyboard(int arg); int mouse(int arg); int USB(int arg); private: //something like cpu ,video card,memory... };
然后我们继续思考,怎样构建我们的私有成员,也就是我们电脑外壳下面的各式部件,或许急于编程的新手会这么做,为每一个部件构建一个类,然后将他们放置与computer下,就像这样子
class CPU { //doSomething }; class VideoCard { //doSomething }; class Memory { //doSomething }; class Computer { public: Computer(/* args */); ~Computer(); int keyboard(int arg); int mouse(int arg); int USB(int arg); private: CPU* mCPU; Memory* mMemory; VideoCard* mVideoCard; void doSomething(); };
我们暂时不管构造函数的与其他东西的实现(事实上,一个好的类库,仅仅依靠接口以及一定的注释就能让使用者明白这个东西)但是,这违反了类的一个原则,代表一类事物,类,是一类事物的抽象,对于具体的事物我们可以对其进行特化,但不应该直接将其定位一类,在这里,不是一类了,而是一个。所以,我们要对cpu,memory等进行一个抽象,他们在计算机中的共同之处是什么?对,有一个我们反复强调的词,部件,component,电脑由多个component所构成,cpu是一个,memory是一个,包括鼠标,键盘也是一个,所以我们构建一个新的类,component,他将包含每个部件都应该有的一些东西,或者还有一些纯虚函数
,更改我们的代码到如下形态
class Component { public: Component(std::string type) :ctype(type){} private: std::string ctype; virtual void doSomethingEveryComponentCanDo(); };
class Computer { public: Computer(/* args */); ~Computer(); int keyboard(int arg); int mouse(int arg); int USB(int arg); private: Component* CPU; Component* memory; Component* videoCard; void doSomethind(); };
而在这之后,我们才可以进行类的特化,所谓类的特化,就是通过继承的方式,把对某一大类的抽象的基类细化为针对某一明确类型的东西,如之前所说的,有些人可能以上来直接建立一个针对某一对象的类,有时候,在一些比较特殊或比较简单的时候,的确可以这样做,但是,在一个比较大而复杂的环境中,明确的继承,基于抽象的细化会获得更好的效果,也更易于理解和更改,基础的方式也易于实现基于虚函数的多态实现,我们再次更改我们的代码,通过继承新建三个类,再一次更改我们的computer类
class Component { public: Component(std::string type) :ctype(type){} private: std::string ctype; virtual void doSomethingEveryComponentCanDo(); };
class CPU :public Component
{
CPU(/* args*/) :Component("CPU"){}
void doSomethingOnlyCPUCanDo();
};
class Memory :public Component
{
Memory(/* args*/) :Component("Memory"){}
void doSomethingOnlyMemoryCanDo();
};
class VideoCard :public Component
{
VideoCard(/* args*/) :Component("VideoCard"){}
void doSomethingOnlyVideoCardCanDo();
};
class Computer
{
public:
Computer(/* args */);
~Computer();
int keyboard(int arg);
int mouse(int arg);
int USB(int arg);
private:
CPU* mCPU;
Memory* mMemory;
VideoCard* mVideoCard;
void doSomething();
};
这就是一个比较好的实现,继承公有属性并拥有特殊能力的部件通过组合得到了电脑,外加虚函数的使用可以让这些部件适应给多的接口,还有一点,劲量将简单的接口暴露给别的个体,这在具有多个类的时候实现松耦合非常重要,类与类之间,商定了通讯协议后绝对不能通过某种方法,使数据通过非公有函数,非正常渠道传递,否则的话后果就是函数的高度耦合,高度耦合会给两边类带来灾难性的后果,依旧是计算机这个例子,我们将其映射到真实世界中,用面向对象思维做一点对比。
人用计算机,这是双边关系,我们将其作为两个类,人对计算机通讯依靠是鼠标与键盘的事件,USB,计算机对人的通讯依靠显示器,如果有一方失效了,另一方不会有任何损失,计算机的键盘失效了,我们依旧敲,然后从显示屏上得到的数据判断出有问题,我们不敲了,可以喝杯咖啡,人什么问题都没有,鼠标也一样;而人有问题了,乱敲键盘,计算机依旧正常响应他能响应的命令,这就是低耦合,一边出问题对别的类影响并不大,而高耦合是什么呢?
我们幻想一个疯狂的情形,我们把计算机的键盘给扯了,直接使用内部的电路对电脑操作,也就是说,我们通过了某种非常不可理喻的方法直接通过private成员操作了数据,然后我们应为某些原因间歇性的发疯,拿起操起一把刀往电脑电路一顿砍,没有了外壳的保护,内部电路被疯狂的我们轻易的砍的一塌糊涂(这只是个比喻,现在的电脑能不能抗住刀砍还真没试过),然后电脑炸了,电火花把人也给炸了,很疯狂,不是么,但是我相信很多人面对一个由十几个,几十个高度耦合的类组成的项目时,真的会有那刀砍电脑的冲动,当然了,是这个项目作者的电脑
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- 一步一步跟我学易语言之第二个易程序菜单设计
- 一个简单的asp数据库操作类
- C#实现用于操作wav声音文件的类实例
- 在线管理数据库 类
- Lua中调用C++函数示例
- Lua面向对象之类和继承浅析
- Lua中类的实现原理探讨(Lua中实现类的方法)
- Lua教程(一):在C++中嵌入Lua脚本
- Lua中的类编程代码实例
- Lua教程(二):C++和Lua相互传递数据示例
- C#常用目录文件操作类实例
- c# 类和成员的修饰详细介绍
- C#中实现判断某个类是否实现了某个接口
- C#类的创建与初始化实例解析
- C#基础语法:结构和类区别详解
- 深入c# 类和结构的区别总结详解