思考:如何设计好一个类?

c++程序员应该如何设计好一个类?如何去思考?怎样才能作为一个优秀的类设计者?

一个优秀的类设计者都有一个核查表,它并不是任务清单。其作用是帮助你回忆起可能会忘记的事情,而不是来约束你。

下面就是设计类时我们应该想到的问题(重在思考,而不是按部就班):

1.你的类需要一个构造函数吗?

过于简单的类可能并不需要构造函数,它们的结构就是接口,所以并不需要构造函数。当我们需要隐藏类的内部工作方式时,就需要构造函数来满足。

2.你的数据成员是私有的吗?

c++五大特性之一就有封装和信息隐藏,通过对象成员属性的定义来实现对象的封装处理,即把他的部分数据和功能对外界屏蔽起来,使外界不用知道,甚至不能知道。两大好处:一是大大降低人们使用对象的难度,使用者完全不用理会里面是怎样实现的。二是可以对知识产权进行保护,通过细致的设计,可以把想隐藏的隐藏起来,只留些接口给类的使用者,使用者无法对现有功能进行修改,也不能知道现有功能是如何实现的,从而实现信息隐蔽。这就是为什么对外的接口一般都是函数。

3.你的类需要一个无参的构造函数吗?

当我们设计类时,想声明类的对象可以不必显式地初始化数据成员时,就得需要一个无参的构造函数。如何设计构造函数就在于你想如何初始化对象。其中有一个注意点,如果一个类需要显式构造函数(带参),不要试图生成该类的对象的数组,这样是非法的。

4.是不是每个构造函数都会初始化所有的数据成员?

构造函数的用途就是用一种明确定义的状态来设置对象。对象的状态由对象的数据成员进行反映。因此每个构造函数都要负责为所有的数据成员设置经过明确定义的值。这说法也未必总是正确的,因为类中可能会有一些数据成员,只在它们的对象存在了一定时间之后才有意义。

5.类需要析构函数吗?

都知道并不是所有有构造函数的类都需要析构函数。什么情况下需要呢?设计类时是否会分配了内存资源,那些资源是否会由成员函数自动释放。分配了未释放,此时就需要一个析构函数。

6.类需要一个虚析构函数吗?

虚析构函数通常都是空的。有些类中声明只是为了声明它们的析构函数是虚的。一般情况下都是需要用作基类的类会需要虚析构函数,因为虚函数只在继承的情况下才有用。如果用基类的指针指向一个子类的类型对象时,虚析构函数就是非常重要的。它能决定你是否正确的调用析构函数。

7.你的类需要复制构造函数吗?

思考的关键就在于复制该类的对象是否就相当于复制其他数据成员和基类对象。如果并不相当,就需要复制构造函数。如果你的类在构造函数内分配资源,则可能就需要一个显式的复制构造函数来管理资源。这里就相当于设计到类浅拷贝还是深拷贝。

8.你的类需要一个赋值操作符吗?

如果需要复制构造函数,同理多半也会需要一个赋值操作符。如果不想用户设置类中的对象,可以选择将其私有化。

如果需要,类X的赋值由X::operator=来定义,通常返回X&,并且有return *this;结束以保证与内建的复制操作符一致。

9.你的赋值操作符能正确地将对象赋给对象本身吗?

普遍赋值总是用新值取代目标对象的旧值。如果原对象与目标对象是同一个,而我们又奉行“先释放旧值,再赋值”的行事规程,就可能在还未实施复制之前就把原对象销毁了。设计时需要注意这种情况,简单的解决方法如下:

X& X::operator=(const X& s)  //这里X是类名
{

    if(&s != this)
    {
        .....
    }
    return *this;
}

或者将旧的目标值保存下来,直到原值复制完成。

10.你的类需要定义关系操作符吗?

如果你的类的值有某种排序关系,就可能需要提供一些需要的关系操作符。即使不希望用户直接使用关系操作符,也可能需要这些关系操作符。只要它们想创建你的类型的有序集合,就必须提供关系操作符。

11.对象、成员函数、引用参数、参数类型是否需要添加const?

如果你理解const的用法就不会纠结此问题。

①const修饰类对象时,其对象中的任何成员都不能被修改。const修饰的对象,该对象的任何非const成员函数都不能调用该对象,因为任何非const成员函数都会有修改成员变量的可能。

②const修饰的成员变量不能被修改,同时只能在初始化列表中被初始化,因为常量只能被初始化,不能被赋值;

③const成员函数表示该成员函数不能修改类对象中的任何非const成员变量。一般const写在函数的后面,形如:void func() const,如果某个成员函数不会修改成员变量,那么最好将其声明为const,因为const成员函数不会对数据进行修改,如果修改,编译器将会报错;

④const在函数声明中使用,修饰形参时,用相应的变量初始化const常量,在函数体内,按照const所修饰的部分进行常量化;

修饰函数返回值时,一般情况下,const修饰返回值多用于操作符的重载。

 

以上就是设计类时应该思考的问题,其作用是提醒我们思考它们,并确认你所做的事情是处于有意识的绝对,而不是偶然性事件。

多思考是程序员的必要因素。加油!

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值