effective c++ 和 more effective c++中知识点

Effective C++

  1. 视 C++ 为一个语言联邦(C、Object-Oriented C++、Template C++、STL)

  2. 宁可以编译器替换预处理器(尽量以 constenuminline 替换 #define

    编译器可以进行类型检查,避免预处理宏可能导致的类型错误。而且比预处理宏更具有可读性和可维护性,方便调试和错误定位,并且编译器对译器可以对 constenuminline 等方式定义的常量进行优化,例如可以将常量直接嵌入到代码中,从而提高代码的执行效率。

  3. 尽可能使用 const

    在 C++ 编程中,尽可能使用 const 可以提高代码的可读性、可维护性和安全性,同时也可以带来一些性能优势。以下是一些常见的情况,可以考虑使用 const

    1. 常量声明
    const double PI = 3.1415926;
    
    1. 函数参数:如果函数不会修改参数的值,应该将参数声明为 const,这可以帮助编译器进行更好的优化,并防止意外修改参数的值。例如:
    void printMessage(const std::string& message);
    

    3.迭代器和指针:如果指针或迭代器指向的对象不会被修改,应该将其声明为指向常量的指针或迭代器。例如:

    const int* ptr;
    const_iterator it;
    
    1. 成员函数中的成员变量:在成员函数中,如果成员变量不会被修改,应该将其声明为 const,以提高代码的可读性和安全性。例如:
    class MyClass {
         
         
    public:
        int getValue() const {
         
         
            return value;
        }
    private:
        int value;
    };
    
  4. 确定对象被使用前已先被初始化(构造时赋值(copy 构造函数)比 default 构造后赋值(copy assignment)效率高

    "default 构造后赋值(copy assignment)"指的是使用默认构造函数创建对象后,再通过赋值运算符(copy assignment operator)将另一个对象的值赋给该对象。

    class MyClass {
         
         
    public:
        int value;
    
        // 默认构造函数
        MyClass() : value(0) {
         
         }
    
        // 赋值运算符(copy assignment operator)
        MyClass& operator=(const MyClass& other) {
         
         
            if (this != &other) {
         
          // 检查是否是自我赋值
                value = other.value;
            }
            return *this;
        }
    };
    
    int main() {
         
         
        MyClass obj1; // 使用默认构造函数创建对象 obj1
        MyClass obj2; // 使用默认构造函数创建对象 obj2
    
        obj2 = obj1; // 使用赋值运算符将 obj1 的值赋给 obj2
    
        return 0;
    }
    
  5. 了解 C++ 默默编写并调用哪些函数(编译器暗自为 class 创建 default 构造函数、copy 构造函数、copy assignment 操作符、析构函数)

  6. 若不想使用编译器自动生成的函数,就应该明确拒绝(将不想使用的成员函数声明为 private,并且不予实现)

  7. 为多态基类声明 virtual 析构函数(如果 class 带有任何 virtual 函数,它就应该拥有一个 virtual 析构函数

  8. 别让异常逃离析构函数(析构函数应该吞下不传播异常,或者结束程序,而不是吐出异常;如果要处理异常应该在非析构的普通函数处理)

  9. 绝不在构造和析构过程中调用 virtual 函数(因为这类调用从不下降至 derived class)

  10. operator= 返回一个 reference to *this (用于连锁赋值)

    这句话的意思是在重载赋值运算符(operator=)时,让它返回一个对当前对象的引用,通常是 *this。这样做的目的是为了支持连锁赋值操作,即可以通过连续地对同一对象进行赋值操作。

    考虑下面的示例:

    class MyClass {
         
         
    public:
        int value;
    
        // 重载赋值运算符
        MyClass& operator=(const MyClass& other) {
         
         
            if (this != &other) {
         
         
                value = other.value;
            }
            return *this; // 返回对当前对象的引用
        }
    };
    
    int main() {
         
         
        MyClass obj1, obj2, obj3;
        
        // 连锁赋值操作
        obj1 = obj2 = obj3;
    
        return 0;
    }
    

    在这个例子中,operator= 被重载为返回对当前对象的引用 *this。因此,连锁赋值 obj1 = obj2 = obj3 的执行顺序是从右向左,首先 obj2 = obj3 被执行,然后返回对 obj2 的引用,接着 obj1 = obj2 被执行,并返回对 obj1 的引用。这样就实现了连锁赋值操作。

    如果 operator= 没有返回引用,则无法进行连锁赋值操作,因为每次赋值操作都会返回一个新的对象,而不是对原始对象的引用。因此,重载赋值运算符时通常会让它返回一个对当前对象的引用,以支持连锁赋值操作。

  11. operator= 中处理 “自我赋值”

    // 重载赋值运算符
    MyClass& operator=(const MyClass& other) {
         
         
        // 检查自我赋值
        if (this != &other) {
         
         
            // 删除旧资源
            delete data;
            // 分配新资源并复制数据
            data = new int(*other.data);
        }
        return *this;
    }
    
  12. 赋值对象时应确保复制 “对象内的所有成员变量” 及 “所有 base class 成分”(调用基类复制构造函数)

    #include <iostream>
    
    // 基类
    class Base {
         
         
    public:
        int baseValue;
    
        // 基类构造函数
        Base(int value) : baseValue(value) {
         
         }
    
        // 基类复制构造函数
        Base(const Base& other) : baseValue(other.baseValue) {
         
         }
    
        // 基类赋值运算符重载
        Base& operator=(const Base& other) {
         
         
            if (this != &other) {
         
         
                baseValue = other.baseValue;
            }
            return *this;
        }
    };
    
    // 派生类
    class Derived : public Base {
         
         
    public:
        int derivedValue;
    
        // 派生类构造函数
        Derived(int base, int derived) : Base(base), derivedValue(derived) {
         
         }
    
        // 派生类复制构造函数
        Derived(const Derived& other) : Base(other), derivedValue(other.derivedValue) {
         
         }
    
        // 派生类赋值运算符重载
        Derived& operator=(const Derived& other) {
         
         
            if (this != &other) {
         
         
                Base::operator=(other); // 调用基类赋值运算符重载
                derivedValue = other.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值