C++之歌——噢,我亲爱的++

本文探讨了C++中的封装、模板和RAII等核心特性,通过实例展示了如何使用这些机制提高代码的灵活性、容错性和效率。通过对圆类的设计,讨论了过度OO的弊端,并提出使用非成员函数和模板来增强接口的灵活性。同时,介绍了资源管理的RAII原则,以确保异常安全。C++的这些基础特性对于程序员的实践至关重要。
摘要由CSDN通过智能技术生成
编程是艺术,这无可否认。不信的去看看高大爷的书就明白了。艺术对于我们这些成天挤压脑浆的程序员而言,是一味滋补的良药。所以,在这个系列中,每一篇我打算以艺术的形式开头。啊?什么形式?当然是最综合的艺术形式。好吧好吧,就是歌剧。当然,我没办法在一篇技术文章的开头演出一整部歌剧,所以决定用一段咏叹调来作为开始。而且,还会尽量使咏叹调同文章有那么一点关联,不管这关联是不是牵强。

噢,我亲爱的++

普契尼的独幕歌剧歌剧《贾尼·斯基基》完成于1918年,同年初演于纽约。

本剧的剧情取自意大利诗人但丁(1265 1321)的长诗《神曲·地狱篇》中的一个故事:富商多纳蒂死了。其遗嘱内,将遗产全数捐献给某一教堂。在场亲友大失所望。众人请贾尼·斯基基假扮多纳蒂,骗过公证人,另立遗嘱,遗产由众亲友均分。公证人到场。结果斯基基将少量遗产分与众人,大部分留给了自己。遗嘱录毕,公证人离去。众大哗,斯基基从病榻跃起,持棒驱散众人。

剧中斯基基的女儿劳蕾塔为表达对青年努奇奥的爱情,对其父唱起了这首美妙绝伦的咏叹调——“我亲爱的爸爸”:

“啊 ! 我亲爱的爸爸,我爱那美丽少年。
我愿到露萨港去,买一个结婚戒指。
我无论如何要去,假如您不答应,
我就到威克桥上,纵身投入那河水里。
我多痛苦,我多悲伤。
! 天哪 ! 我宁愿死去 !
爸爸,我恳求你 !
爸爸,我恳求你 !

 

按照C/C++中对于后置操作符++的定义,操作数增加1,并返回原来的值。于是,有人根据这个给C++遍了一段笑话,流传甚广。那么,C++是否相对C加了那么一点点,然后还是返回原来的值呢?那就让我们来“实地考察”一下,了解这个++究竟加了多少。

我不打算罗列C++的各种纷繁复杂的特性。已经有无数书籍文章做了这件事,肯定比我做的好得多。我要做的,是探索如何运用C++的一些机制,让我们能够更方便、快捷、容错地开发软件。这些特性很多都是非常简单的,基本的。正因为它们基本,很容易为人们所忽略。另一些则是高级的,需要多花些时间加以掌握的。但是,这些特性也具有一些简单,但却非常实用、灵活和高效的用法。

相对于CC++最主要的变化就是增加了类。严格地讲,类是一种“用户定义类型”,是扩展类型系统的重要手段。类从本质上来说,是一种ADTAbstract Data Type,抽象数据类型)。笼统地讲,ADT可以看作数据和作用在这些数据上的操作的集合。

类提供了一种特性,称为可见性。意思是说,程序员可以按自己的要求,把类上的数据或函数隐藏起来,不给其他人访问。于是,通过可见性的控制,可以让一个类外部呈现一种“外观”,而内部可以使用任何可能的方法实现类的功能。这称为“封装”。

呵呵,听烦了吧。这些东西是学过C++(或者任何时髦的OOP语言)的都已经烂熟于胸了。这样的话,我们就来点实际的,做个小案例,复习复习。温故而知新嘛。:)

案例非常简单,做一个圆类。让我们从“赤裸”的C结构开始吧:

struct  Cycle
{
   
float    center_x;
   
float    center_y;
   
float    radius;
};
        很传统的表示, < 圆心坐标,半径 > ,便可以立刻定义出一个圆形。现在,假设我们需要计算圆形的面积。于是,我写了一个函数执行这项任务:
float  Area( const  Cycle  &  rc)  {
   
return  PI*rc.radius*rc.radius;
}
    很好。但是突然有一天,我心血来潮,把圆形类的存储改成外切正方形的 < 左上角,右下角 > 形式,那么这个函数就不能用了。为了让我这么一个三心二意的人能够得到满足,就得运用封装这个特性了:
class  Cycle
{
public :
   
float  get_center_x() {  return  left; }
   
float  get_center_y() {  return  top; }
   
float  get_radius() {  return  bottom; }

private :
   
float    center_x;
   
float    center_y;
   
float    radius;
};

然后,面积计算公式稍作改动就行了:

float  Area( const  Cycle  &  rc) {
   
return   PI * rc. get_radius() * rc. get_radius();
}

这时,如果我改变了Rectangle的数据存储方式,也不会影响Area函数:

class  Cycle
{
public :
   
float  get_center_x() {  return  (left + right) / 2 ; }
   
float  get_center_y() {  return  (top + bottom) / 2 ; }
   
float  get_radius() {  return  (right - left) / 2 ; }

private :
   
float    left;
   
float    top;
   
float    right;
   
float    bottom;
};

运用了封装之后,类的实现和接口分离了。于是我们便可以在使用方神不知鬼不觉的情况下,改变我们的实现,以获得更好的利益,比如效率的提升、代码维护性的提高等等。

当我们尝到封装的甜头之后,便会继续发扬光大:

class  Cycle
{
public
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值