c++类的编程规范

     类是c++中必不可少的一部分,类是面向对象(oo)的基础,是一个非常强大的功能,也是c++中最容易被滥用的功能之一。

类是应面向对象而诞生的,而过度并且无脑的面向对象,使程序大幅度的包装,无谓的抽象,以及本身对类的使用不规范,导致了大量无谓低效的代码诞生,本章讲解的就是博主对类的使用的一点理解。

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成员操作了数据,然后我们应为某些原因间歇性的发疯,拿起操起一把刀往电脑电路一顿砍,没有了外壳的保护,内部电路被疯狂的我们轻易的砍的一塌糊涂(这只是个比喻,现在的电脑能不能抗住刀砍还真没试过),然后电脑炸了,电火花把人也给炸了,很疯狂,不是么,但是我相信很多人面对一个由十几个,几十个高度耦合的类组成的项目时,真的会有那刀砍电脑的冲动,当然了,是这个项目作者的电脑




  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值