• EC++学习笔记(一) 习惯c++


    条款01:c++多范式编程语言
    条款02:尽量以 const, enum, inline 替换#define

    1. 提供类型安全检查

    2. 去除函数调用开销

    3. 避免宏的二义性

    const double pi = 3.1415926;
    const std::string authorName("wwwjieo0");

      宏函数:所有实参必须加上小括号

    #define MAX(x, y)  ((x) >= (y) ? (x) : (y))
    MAX(++a, b);    //a被累加两次

      c++ inline函数实现:

    template<class T>
    inline T max(const T& x, const T& y) {
        return (x >= y ? x : y);
    }

      

    c语言中的宏仍然是必需品:
    #include是必需品,#ifdef和#ifndef扮演 条件编译的角色

    条款03:尽可能使用const

    const 使编译器实施强制保护

    char myname[] = "wwwjieo0";
    char* p = myname;                   //non-const pointer, non-const data
    const char* p = myname;            //non-const pointer, const data
    char* const p = myname;            //const pointer, non-const data
    const char* const p = myname;     //const pointer, const data

      STL迭代器的const:

    const std::vector<int>::iterator it = vec.begin();    //it为const,永远指向begin
    std::vector<int>::const_iterator it = vec.begin();    //it可以改变,但*it(即容器元素)不可改变

    const 成员函数:

    const 成员函数不可以更改对象任何non-static 成员变量

    可以利用 const 成员函数实现其non-const 版本

    const Widget& func(int x, int y) const; //已经实现
    Widget& func(int x, int y) {
        return const_cast<Widget&>(static_cast<const Widget&>(*this).func(x, y));
    }

    类中的每个non-static 成员函数都有一个隐藏的this参数(第一个参数),这个this指针指向类的实例对象,并且this指针为const pointer
    所以 Widget& func(int x, int y) 实际上是 Widget& func(Widget* const this, int x, int y);
    而 const 成员版本 Widget& func(int x, int y) const 实际上是 Widget& func(const Widget * const this, int x, int y);
    (const int& x)和 (const int x)是重载函数,并不是重复定义

    static_cast 将(*this) 加上 const 特性,因为要调用 const 成员函数
    const_cast 将 const 成员函数返回值 const Widget& 去除 const 特性,因为要与函数返回值类型相同

    注意:不能用non-const 成员函数去实现相应的 const 版本,因为 non-const 函数可能会改变一些值,这不符合 const 函数的要求

    条款04:确定对象被使用前已被初始化

    永远在使用对象之前先将它初始化
    内置类型:手工初始化,避免未定义行为带来的随机值
    自定义类型:确保每一个构造函数都将对象的每一个成员初始化

    class Person{
    public:
        Person(const string& name, const string& address);
    private:
        string    theName;
        string    theAddress;
        int       theId;
    };
    
    Person::Person(const string& name, const string& address) {
        theName = name;
        theAddress = address;
        theId = 0;
    }

    c++规定,对象的成员变量的初始化动作发生在进入构造函数的函数体之前
    所以上面程序中,构造函数内部并不是初始化,而是赋值操作
    真正的初始化动作发生在 default 构造函数(编译器自动生成)自动调用之时

    构造函数应该使用 成员初始化列表 替换赋值操作

    Person::Person(const string& name, const string& address)
    :theName(name),
    theAddress(address),
    theId(0)
    { }

    这种方法效率更高,没有首先调用 default 构造函数,而是在进入构造函数的函数体之前利用 copy构造函数直接初始化
    总结:总是使用成员初始值列表,并且在初值中列出所有成员变量

    c++初始化次序:base class 更早于 derived class,class 的成员变量总是以其声明次序被初始化

  • 相关阅读:
    【POJ】1204 Word Puzzles
    【POJ】1816 Wild Words
    【HDOJ】1247 Hat’s Words
    【HDOJ】2609 How many
    【POJ】1035 Spell checker
    【POJ】2418 Hardwood Species
    【POJ】1056 IMMEDIATE DECODABILITY
    数列有序!
    绝对值排序
    C语言合法标识符
  • 原文地址:https://www.cnblogs.com/wwwjieo0/p/3442892.html
Copyright © 2020-2023  润新知