• 条例1~5


    目录

    条例二

    尽量用const,enum,inline,替换#define

    the enum hack 补偿法

    使用宏替换函数的时候务必给所有实参加上小括号

    总结

    条例三

    const对于指针来说左定值右定向

    函数返回值最好带上const,防御性编程,这样能防止某些不合法的操作

    成员函数是const的意义

    cont和non const 成员函数避免重复

    总结

    条例四

    确定对象使用前已经被初始化

    总结

    条例五

    c++默认生成的成员函数

    总结


    条例二

    尽量用const,enum,inline,替换#define

    • 宏替换不会进符号表,会在处理源码时直接替换,若出现报错将会导致可读性差。可用常量替换宏。
    • 宏替换会导致代码量增大。
    • 宏定义不能提供任何封装性,无法define一个class的专属常量

    the enum hack 补偿法

    • 一个属于枚举类型的数值可以充当int使用,可以用于数组大小的声明。这种做法类似宏替换

    使用宏替换函数的时候务必给所有实参加上小括号

    • 尽量少用这种方法,可以通过模板参数加内联函数得到同样的效果

    总结

    • 对于单纯的常量,最好用const 或enums  替换宏
    • 对于函数,最好用内联替换宏

    条例三

    const对于指针来说左定值右定向

    函数返回值最好带上const,防御性编程,这样能防止某些不合法的操作

    比如说不小心对函数返回值进行赋值。

    成员函数是const的意义

    • 两个流行概念bitwise const 和 logical constness,前者指的是成员函数不更改对象内的任何变量。(好处是编译器至于需要检查成员变量是否有赋值动作,缺点是可以过指针绕过强行修改。比如说返回指针引用,然后客户对指针解引用并修改它的值)后者指的是const成员函数可以修改成员变量,但要在用户不知道的情况下。当你你的成员函数添加了const的时候,成员变量可能需要修改,但这时编译器坚持bitwise const,就会出现编译报错。可以用mutable释放掉non static成员变量的bitwise const约束。

    cont和non const 成员函数避免重复

    • 函数传参的时候const 变量 无法调用非const的成员函数。但非const参数可以调用const成员函数,这里有权限匹配的问题,缺陷只能相等或者缩小不能放大。
    • 我们可以用非const成员函数复用const成员,提高代码的复用程度。在想要使用non const成员函数的时候,我们先可以用static cast 关键字对当前this指针添加上const属性,再复用const成员函数,最后拿到结果后再用const cast 关键字去掉const 属性。(虽然理论上non const 对象可以直接调用 const函数,但此时我们若不添加上const 属性,这调用的就是它本身也就是非const函数,就会陷入无穷递归,我们需要强制添加上const属性,这样才会调用const成员函数)
    • 注意点,只能用non const成员函数复用const 成员函数。因为const成员函数需要保证内部成员不被改变,若反着用就会存在改动风险

    总结

    • 若条件允许,可以用non const 函数复用const函数
    • 编译器强制实施 bitwise constness
    • 函数尽量声明为const 可以帮助编译器检查出错误用法

    条例四

    确定对象使用前已经被初始化

    • 尽量使用初始化列表代替函数内初始化。因为在构造函数内部无论你是否使用初始化列表,他都会先通过初始化列表自动构造成员变量(自定义函数调用其自身的构造函数,内置类型不处理)再在函数体内部对这些成员进行复制。若我们直接调用初始化列表初始化,他将直接调用拷贝构造。这样可以从 构造函数+赋值 优化到 拷贝构造 提高效率。
    • 继承的父类成员变量优先初始化,当前成员变量后初始化。初始化列表的初始化顺序是由声明顺序决定的。与初始化列表的顺序无关。
    • 不同编译文件之间的非局部静态对象(不再函数内定义的)初始化顺序是无法确定的。这时若两个不同文件内的静态对象存在先后依赖关系,就会出现错误。这时可以通过类似单例模式解决。将非局部静态变量搬到自己的专属函数内,通过函数去调用这些静态变量,也就是让非局部静态变量成为局部静态变量。这样所另一个好处就是,若你不调用这个获取静态变量的函数,就不会产生构造和析构的成本。要点就是虽然非局部静态变量初始化顺序不可控,但是局部静态变量的初始化顺序是可控的。(但是这样做的缺点是在多线程环境下可能出现问题)

    总结

    • 内置对象都要手动初始化,编译器不会保证会自动初始化
    • 最好使用初始化列表初始化,同时初始化列表的排列顺序最好的声明顺序一致
    • 多文件编译最好用静态变量替换局部静态变量,这样能确保初始化顺序

    条例五

    c++默认生成的成员函数

    • 空类编译器会自己生成拷贝构造,拷贝赋值,析构函数,若自己没实现析构,还会生成默认析构。
    • 拷贝构造和拷贝赋值默认是值拷贝
    •  若条件不允许,有时候编译器会拒绝生成拷贝赋值操作。当成员变量是引用的时候,当初成员变量是const,基类的拷贝赋值为私有,想要默认生成子类拷贝赋值,时编译器会拒绝赋值操作。这种情况只能自己实现拷贝赋值操作

    总结

    • 编译器可以暗自生成构造,析构,拷贝,赋值等成员函数

  • 相关阅读:
    自动化测试如何管理测试数据
    记一次因为没有关闭 管道导致的内存泄露
    GEO生信数据挖掘(七)差异基因分析
    Jprofiler的使用查看oom
    Spring 编程常见问题之一(专栏学习笔记)
    .NET基础面试题
    【操作系统导论】操作系统介绍 - Introduction
    JavaScript-day03学习(流程控制)
    c++ 函数重载
    详解GaussDB(DWS)中的行执行引擎
  • 原文地址:https://blog.csdn.net/m0_62572672/article/details/132865032