C++学习笔记----5、重用之设计(一)---- 重用的哲学

2024-08-25 20:36

本文主要是介绍C++学习笔记----5、重用之设计(一)---- 重用的哲学,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        设计的代码你和其他的程序员应该都可以重用。这条规则不但适用于让其他程序员特别使用的库与框架,也适用于任何类、子系统或者为程序设计的部件。一定要记住如下的格言:

  • 一次编写,多次使用。
  • 尽量避免重复代码
  • 不要重复你自己。

原因如下:

  • 很少有代码只在一个程序中使用。要确信你的代码不管怎么样都会被再次使用,所以一开始就要正确地进行设计。
  • 设计重用的代码可以节省时间与金钱。如果你设计的代码不考虑未来的使用,当你碰到 类似功能的需求时,就会花费大量的时间重新造轮子。
  • 其他程序员一定能够使用你写的代码。你不会一个人在一个项目中工作。同事会感激你提供的良好设计,打包功能的库以及代码的努力。重用的设计也可以被叫做合作编码。
  • 缺乏重用就会有代码重复;代码重复就会造成维护梦魇。如果在一个重复的代码中发现了bug,就需要在它重复的所有地方进行修复。如果你发现自己在复制粘贴代码,就必须至少要考虑一下是否可以提炼到一个函数或类中。
  • 你是自己工作最大的受益者。有经验的程序员从来不会摒弃代码。随着时间的推移,他们建立了一个不断演化的个人库。你永远不会知道将来你会需要类似功能的代码。

        当然了,我喜欢这么说,对于重用,不可避免地会涉及到知识产权的问题。这个问题其实与我们学习C++编程无关,是另外一个领域的话题,我只是要说明,为公司干的工作成果,其知识产权是公司的,离职后对这些代码的重用一定要基于合法的前提。但与我们要讲的重用之哲学其实不矛盾,你不这么认为么?

如何设计可重用的代码

        可重用的代码完成如下两个目标:

  • 首先,是要对稍微不同的目的或者在不同的应用域中一般够用。特定应用的带有细节的部件在其它程序中重用是困难的。
  • 其次,可重用的代码也是易用的。不需要花费太长的时间去理解其接口与功能。程序员必须能够逐渐将其整合进他们的应用。

        将库交付给用户的方式也很重要。可以以源代码的方式交付,客户只需要将你的源代码整合进他们的项目中即可。另一种方式就是以静态库的方式交付二进制代码,链接进他们的应用,或者是用动态库的方式,在Windows环境下是.dll文件,在Linux环境下是.so文件。不同的交付方式对于如何设计可重用的代码的限制是不一样的。

        设计可重用的代码最重要的策略就是抽象。

使用抽象

        抽象的关键就是将接口与实现进行了隔离。实现就是你要写的代码,去完成你要完成的任务。接口就是其他人使用你的代码的方式。在C中,头文件揭示了你要在接口中写的库的函数声明。在面向对象的程序设计中,可以公开访问的类成员函数与类属性就是类的接口。然而,一个好的接口应该只包含公共的成员函数。类的属性永远不要变成公共的,但是可以通过公共的成员函数来向外部暴露。公共成员函数也叫做get()与set()。

        以前我们介绍过抽象的原则,讲过一个真实世界中的对于电视的分析,你可以在不理解其内部是如何工作的情况下通过接口赤使用。同样的,在设计代码时,也要将实现与接口清楚地分开。这种分隔使代码易于使用,主要是因为用户不需要理解内部实现的细节就可以使用其功能。

        使用抽象对你与使用你的代码的用户都有好处。用户有好处是因为他们不需要担心实现细节;可以在不理解代码怎么干活的情况下利用其功能。这样的话,就可以不要求用户改变其使用的情况下升级你的代码。对于动态链接库,用户甚至不需要重新构建其可执行程序。最后,对双方都有好处是因为,对于你,库作者,可以指定接口,按照你想要的交互,以及你想要的支持功能来指定。对于接口与实现的隔离或以防止用户以你不想要的方式来使用库,因为这种使用方式可能会引起不可预知的行为和问题。

        设计接口时,不要向用户暴露实现细节。

        有时候库会要求用户代码保留从一个接口返回的信息并将其传递给另一个。这种信息有时候会叫做一个句柄,常用于在不同的调用之间跟踪特定实例的状态。真实世界的例子就是OpenGL,一个2D/3D优化库。OpenGL的许多函数返回句柄,操作句柄,以GLuint的类型出现。例如,如果你要用OpenGL函数glGenBuffers()来生成一个缓存,它返回GLuint句柄。任何时候你要调用另一个函数来结这个缓存进行操作的时候,都必须把GLuint句柄传递给那个函数。

        如果你的库设计需要一个句柄,不要暴露其内部。使其成为一个透明的类,程序员无法访问其内部数据成员,不管是直接还是通过get()与set(),都不行。不要要求用户代码在句柄内部调整变量。不好的设计例子就是要求在一个假定透明的句柄中指定特定结构成员的值,比如为了打开错误日志。

        不幸的是,C++对于类的抽象原则很不友好(当然了,从另一个角度来说,它提供了方便性)。语法要求你将public接口与non-public(private或者protected)数据成员和成员函数放到一个类定义中,这样的话,就会把类的实现细节暴露给了用户。

        抽象是如此重要,以至于它要在整个设计中对你进行指导。你所做出的每一个决定,都要问问你自己,你的选择是否遵从了抽象的原则。站在用户的角度来决定是否在接口中包含了内部实现的知识细节。可能,很偶尔地,你会破坏这个规则。

        当使用抽象原则进行可重用代码设计时,应该侧重于以下几点:

  • 首先,必须正确结构化代码。要使用什么样的类层次结构?要用模板吗?如何将代码分成子系统?
  • 其次,要设计接口,该接口就是进入库进行你提供的功能访问的入口。

好了,我们今天讨论的内容不少了,上面的这两个主题我们以后继续聊。

这篇关于C++学习笔记----5、重用之设计(一)---- 重用的哲学的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1106591

相关文章

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

C/C++错误信息处理的常见方法及函数

《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat

详解C++中类的大小决定因数

《详解C++中类的大小决定因数》类的大小受多个因素影响,主要包括成员变量、对齐方式、继承关系、虚函数表等,下面就来介绍一下,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 非静态数据成员示例:2. 数据对齐(Padding)示例:3. 虚函数(vtable 指针)示例:4. 继承普通继承虚继承5.

C++中std::distance使用方法示例

《C++中std::distance使用方法示例》std::distance是C++标准库中的一个函数,用于计算两个迭代器之间的距离,本文主要介绍了C++中std::distance使用方法示例,具... 目录语法使用方式解释示例输出:其他说明:总结std::distance&n编程bsp;是 C++ 标准

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示