【C++ 实战】概论 | 代码风格 | 类 |生命周期 |

文章目录

  • C++ 程序的生命周期
  • 编程范式
  • 代码风格
    • 注释
  • 预处理阶段 :宏定义和条件编译
    • #include
    • 宏定义(#define / #undef)
    • 条件编译(#if/#else/#endif)
  • 编译阶段 : 属性和 静态断言
    • 编译阶段编程
    • 属性(attribute)
    • 静态断言(static_assert)
  • 面向对象编程
    • 设计思想
    • 实现原则
    • 编码准则
    • 常用技巧
      • 委托构造
      • “成员变量初始化”(In-class member initializer)。
    • “类型别名”(Type Alias)。
    • 小结

C++ 程序的生命周期

  • 编码(Coding)、预处理(Pre-processing)、编译(Compiling)和运行 (Running)
    【C++ 实战】概论 | 代码风格 | 类 |生命周期 |
    • 面向对象:核心思想是“抽象”和“封装” , 它强调对象之间的关系和,而不是完成任务的具体步骤。
    • 泛型编程:自 STL(标准模板库)纳入到 C++ 标准以后才逐渐流行起来的新范式,核心思想是“一切皆为类型”,使用模板而不是继承的方式来复用代码,运行效率更高,代码简洁。eg.template,vector …
    • 模板元编程: 它的核心思想是“类型运算”,操作的数据是编译时可见的“类型”,所以也比较特殊,代码只能由编译器执行,而不能被运行时 的 CPU 执行。更多的是以库的方式来使用.
    • 函数式: 核心思想是“一切皆可调用”,通过一系列连续或者嵌套的函数调用实现对数据的处
    • 所以常用的范式是“过程 + 对象 + 泛型”,再加上少量的“函数式”,慎用“模板元”。认识、理解这些范式的优势和劣势,在程序里适当混用,取长补短才 是“王道

    代码风格

    代码风格

    • 留白的艺术 : 恰当地运用空格和空行
      【C++ 实战】概论 | 代码风格 | 类 |生命周期 |
    • 注释

      • 给代码配上额外的文字,起到注解、补充说明的作用。
      • 注释必须要正确、清晰、有效,尽量言简意赅、点到为止,不要画蛇添足,更不 能写出含糊、错误的注释。
        【C++ 实战】概论 | 代码风格 | 类 |生命周期 |
      • 预处理程序无法调试,得使用 gcc ‘-E’ 选项 ,略过后面的编译链接,只输出预处理后的源码。 【C++ 实战】概论 | 代码风格 | 类 |生命周期 |

      【C++ 实战】概论 | 代码风格 | 类 |生命周期 |

宏定义(#define / #undef)

  • #define ;文本替换”, “宏定义”

  • 使用宏的时候一定要谨慎,时刻记着以简化代码、清晰易懂为目标,不要“滥用”, 避免导致源码混乱不堪,降低可读性。

    【C++ 实战】概论 | 代码风格 | 类 |生命周期 |
  • 另一种做法是宏定义前先检查,如果之前有定义就先 undef,然后再重新定义:

    【C++ 实战】概论 | 代码风格 | 类 |生命周期 |

条件编译(#if/#else/#endif)

  • #if 判断依据
  • 通常编译环境都会有一些预定义宏.
  • CPU 支持的特殊指令集、操作系统 / 编译器 / 程 序库的版本、语言特性等,使用它们就可以早于运行阶段
  • 宏是“__cplusplus”,它标记了 C++ 语言的版本号。
    【C++ 实战】概论 | 代码风格 | 类 |生命周期 |
    【C++ 实战】概论 | 代码风格 | 类 |生命周期 |
  • 在 C++11 里只定义了两个属性:“noreturn”和“carries_dependency”,它们 基本上没什么大用处。
  • C++14 增加了一个比较实用的属性“deprecated”(弃用的),用来标记不推 荐使用的变量、函数或者类。 可以用在C++11中
  • 几个有用的属性:
    • deprecated:与 C++14 相同,但可以用在 C++11 里。
    • unused:用于变量、类型、函数等,表示虽然暂时不用,但最好保留着,因为将来可能会用。
    • constructor:函数会在 main() 函数之前执行,效果有点像是全局对象的构造函数
    • destructor:函数会在 main() 函数结束之后执行,有点像是全局对象的析构函数。
    • always_inline:要求编译器强制内联函数,作用比 inline 关键字更强。
    • hot:标记“热点”函数,要求编译器更积极地优化。

静态断言(static_assert)

  • assert 吧,它用来断言一个表达式必定为真。比如说,数字必须是正数,指针必须非空、函数必须返回 true:
  • 当程序(也就是)运行到 语句时,就会计算表达式的值,如果是 ,就会输出错误消息,然后调用 终止程序的执行。
  • :立刻程序,没有任何清理工作. 相同的在调用之前一定要释放应该释放的资源.
  • 虽然是一个宏,但在不生效,而是在运行阶段才起作用,所以又 叫。
  • 静态断言:,一个专门的关键字,不是宏。因为它只在编译时生效, 运行阶段看不见,所以是“静态”的。
  • 它是编译阶段里检测各种条件的“断言”,编译器看 到 static_assert 也会计算表达式的值,如果值是 false,就会报错,导致编译失败。
    【C++ 实战】概论 | 代码风格 | 类 |生命周期 |
  • 运行在编译阶段,只能看到编译时的常数和类型
  • 由于变量只能在运行阶段出现,而在编译阶段不存在,所 以静态断言无法处理。
    【C++ 实战】概论 | 代码风格 | 类 |生命周期 |

    面向对象编程

    设计思想

    • 主要就是 : 要点是抽象(Abstraction)和封装(Encapsulation)。
    • 面向对象编程的基本出发点是“对现实世界的模拟”,把问题中的实体抽象出来,封装为程 序里的类和对象,这样就在计算机里为现实问题建立了一个“虚拟模型”。
    • “继承”的本意是重用代码,表述类型的从属关系(Is-A),但它却不能与现实完全对应, 所以用起来就会出现很多意外情况。
    • “面向对象编程”是一种设计思想,要点是“抽象”和“封装”,“继承”“多态”是 衍生出的特性,不完全符合现实世界。

    实现原则

    • 在 C++ 里应当少用继承和虚函数,降低对象的成本,减少冗余代码,提高代码的健壮性,绕过那些难懂易错的陷阱。
    • 如果使用继承的话, 要控制好层次 , 不能超过三层(过分设计).
      【C++ 实战】概论 | 代码风格 | 类 |生命周期 |
    • 在现代 C++ 里,一个类总是会有六大基本函数:三个构造(普通构造、转移构造函数和转移赋值函数)、两个赋值、一个析构.
    • 对于比较重要的构造函数和析构函数,应该用“= default”的形式,明确 地告诉编译器(和代码阅读者):“应该实现这个函数,但我不想自己写。”这样编译器就 得到了明确的指示,可以做更好的优化
      【C++ 实战】概论 | 代码风格 | 类 |生命周期 |
    • 为了防止意外的类型转换,保证安全,就要使用“explicit”将这些函数标记 为“显式”
      【C++ 实战】概论 | 代码风格 | 类 |生命周期 |

      “成员变量初始化”(In-class member initializer)。

      • 在类里声明变量的同时给它赋值,实现初始化,这样不但简单清 晰,也消除了隐患.

      【C++ 实战】概论 | 代码风格 | 类 |生命周期 |

    小结

    1.“面向对象编程”是一种设计思想,要点是“抽象”和“封装”,“继承”“多态”是 衍生出的特性,不完全符合现实世界。
    2. 在 C++ 里应当少用继承和虚函数,降低对象的成本,绕过那些难懂易错的陷阱。
    3. 使用特殊标识符“final”可以禁止类被继承,简化类的层次关系。
    4.类有六大基本函数,对于重要的构造 / 析构函数,可以使用“= default”来显式要求编 译器使用默认实现
    4. “委托构造”和“成员变量初始化”特性可以让创建对象的工作更加轻松。
    5. 使用 using 或 typedef 可以为类型起别名,既能够简化代码,还能够适应将来的变化。

    【C++ 实战】概论 | 代码风格 | 类 |生命周期 |

    来源:Cpt1024

    声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年7月8日
下一篇 2022年7月8日

相关推荐