Effective C++学习笔记(一)

摘要:
条款二尽量使用const,enum,inline代替define。因为define不被视为语言的一部分。建议用内联模板建议对于单纯常量,最好以const对象或者enum替换#define对于形似函数的宏,最好改用inline函数替换条款三尽量使用const。*citer是const;++citer;//没问题!改变citerconst在函数中的运用constRationaloperator*;避免用户XJBY。C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前。

条款一 C++是一个语言联邦

建议

  • c++是有兄弟的:C,Object-Oriented c++(c with class),template c++,STL
  • c++高效编程守则视状况而变化,取决于你使用c++的哪一部分。

条款二 尽量使用const, enum, inline代替define。

  • 宁可编译器替换预处理器比较好。因为define不被视为语言的一部分。

    define NUM 3
    

    define在预处理器中已经替换成为具体的值,当编译遇到一个常量错误的时候,你可能会感到困惑,因为错误信息提到的可能是3,而不是NUM。
    而且当NUM的定义不是你所设计的时候,你可能会因为去查找3这个值所引发的错误到底是为什么而头大!这个问题也可能出现在记号调试器(symbolic debugger)中,原因相同:你所使用的名称可能并未进入记号表(symbol table)
    另一个原因是:const可以成为作用域中的一个成员,define并不能行,且不能提供任何封装性。
    还有一个原因是#define的函数

    #define MAX(a,b) func((a)>(b)?(a):(b))
    int a=5,b=0;
    MAX(++a,b);		     //a被累加二次
    MAX(++a,b+10);	    //a被累加一次
    

    在这里,调用f之前,a的递增次数不定!
    建议用内联模板

建议

  • 对于单纯常量,最好以const对象或者enum替换#define
  • 对于形似函数的宏,最好改用inline函数替换

条款三 尽量使用const。

  • const在常量中的运用。

    char greet[] = "hello";
    const char* p = greet; //const data,non-const pointer;
    char* const p = greet; //non-const data,const pointer;
    const char* const p = greet; //const data,const pointer;
    

    迭代器中:

    vector<int>vec;
    const vector<int>::iterator iter = vec.begin();
    *iter = 10;		 //没问题,改变iter所指的实体;
    ++iter;          //错误!iter是const
    
    //其实看过const_iterator的实现就知道,他就是对实体对象的一个const
    vector<int>::const_iterator citer = vec.begin();
    *citer = 10;		 //错误!*citer是const;
    ++citer;            //没问题!改变citer
    
  • const在函数中的运用

    const Rational operator*(const Rational &lhs);

    避免用户XJBY。

  • const成员函数

    第一,他们使得class接口比较容易理解,可以知道哪个函数可以改动对象内容,哪个函数不行。
    第二,他们使得“操作const对象”成为可能。

  • 编译器强制实施bitwise constness,但你编写程序时应该使用概念上的常量性

  • 当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。但是要做好类型转换,否则会出现自己调用自己的现象。

    const char& operator[] (int position) const
    {
        return m_text[position];
    }
    
    /*  返回类型是个reference to char,不是char  */
    char &operator[](int position)
    {
        return m_text[position];
        /*调用const operator[]*/
        /*
        return const_cast<cahr&>(const TextBlock&)(*this)[position]);
        */
    }
    

建议

  • const真的是一个磨人的小妖精

条款四 确定对象在使用前已经初始化。

  • 为内置型对象进行手工初始化,因为C++不保证初始化它们。

  • 构造函数最好使用成员初始化列表(member initialization list),而不要在构造函数本体内使用赋值操作(assignment)。初值列列出的成员变量,其排列次序应该和它们在class中的声明次序相同。
    C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前。构造函数体内的“=”叫做“赋值”,初始化发生的时间更早,发生于这些成员的default构造函数被自动调用之时。
    赋值构造的实质是:先设定初值,再为它们赋予新值。
    成员列表初始化:避免上述问题,同时避免调用copy构造函数,高效很多

  • 为免除“跨编译单元之初始化次序”问题,请以local static对象替换non-local static对象。(不是很明白)

建议

  • 记得初始化!
  • 可以使用初始化列表

免责声明:文章转载自《Effective C++学习笔记(一)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇python使用multiprocessing创建多线程时异常的解决es更新说明(dsl)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

瀑布流的三种实现方式(原生js+jquery+css3)

前言 项目需求要弄个瀑布流的页面,用的是waterfall这个插件,感觉还是可以的,项目赶就没自己的动手写。最近闲来没事,就自己写个。大致思路理清楚,还是挺好实现的... 原生javascript版 <!DOCTYPE html> <html lang="en"> <head> <meta charset=...

服务器性能自动化测试脚本

1.自动化测试脚本unixbench yum install -y wgetwget --no-check-certificate https://github.com/teddysun/across/raw/master/unixbench.shchmod +x unixbench.sh./unixbench.sh 115.231.102.80: Dou...

react 实现圆环进度条

import React, { useState, useEffect } from "react" import { css } from "emotion" //num是从父级传来的百分比数值 export default function({ num }) { let rightTrnas = css` transform: rotate(0deg)...

Spring RedisTemplate操作-事务操作(9)

@Autowired @Qualifier("redisTemplate") private RedisTemplate<String, String> stringredisTemplate; public void flushdb() { stringredisTemplate.execu...

使用SWIG将C++接口转换成Java接口

PS:此文章仅作为个人记录使用,代码属于私密,故无法公开; 以C++类classifier为例,文件保存于百度网盘 https://pan.baidu.com/s/1c2AwhaS(需密码) 系统:Ubuntu 15.04 参考资料: ubuntu源码安装swig 利用swig转换C++接口到Java接口 SWIG3.0说明文档 编程中出现的错误: ja...

DirectSound---捕获音频、Qml/C++ 集成交互

DirectSound的音频捕获原理和播放原理差不多,内部在一个缓冲区上循环写入捕获到的数据,并且提供notify通知功能。 1. 音频捕获 因为捕获流程和播放流程类似,我们就不在这里赘述了,只给出简单的函数引用和图示: 最后两个是音效捕获接口,用来控制Aec(回声消除)、Noise Fill(噪音填充)、Ns(噪音压制)的开启与关闭: HRESULT D...