Effective(Modern)C++笔记01

本文是《Effective C++》笔记,探讨了C++语言联邦的不同层面,包括C特性、Object-Oriented C++、Template和STL。强调使用const、enum、inline替换#define,以及在构造、析构和赋值运算中的最佳实践,如使用const、初始化、virtual析构函数、避免异常逃离等。还介绍了特种成员函数的生成机制和成员函数模板的规则。
摘要由CSDN通过智能技术生成

Effectice C++01

条款01:视C++为一个语言联邦

  • C

区块(blocks)、语句(statements)、预处理(preprocessor)、内置数据类型(built-in data types)、数组(arrays)、指针(pointers)

  • Object-Oriented C++

classes(包括构造和析构函数)、封装(encapsulation)、继承(inheritance)、多态(polymorphism)、virtual(动态绑定)

  • Template

泛型编程、模板元编程

  • STL

容器、迭代器、算法、函数对象

条款二:尽量以const、enum、inline、替换#define

以编译器替换预处理器

#define ASPECT_ROTIO 1.653 // 可能并未记录到符号表 获取编译错误信息会提到 1.653
						   // 目标码会出现多份1.653
const double AspectRotio = 1.653
// 常量指针
const char* const authorName = "Scott Meyers"
    
// class 专属常量
class GamePlayer {
   
private:
    // 通常需要在外面有定义式
    // static 且为整数类型 int char bool 只要不取它们的地址,可以提供声明式而无需提供定义式
    static const int NumTurn = 5; //声明常量=======================================
    int scores[NumTUr];
}

const int GamePlayer::Numturns; // Numturns的定义 放进一个实现文件
class GamePlayer {
   
private: 
    enum {
   NumTurns = 5}; // the enum hack 无法取地址
    int score[NumTruns];
}
  • 对于单纯常量,最好以const对象或enum替换#define
  • 对于形似函数的宏,最好改用inline函数替换#define

条款03:尽可能使用const

STL迭代器以指针为根据塑模出来,所以迭代器的作用就像一个T*指针。声明迭代器为const对象就像声明指针为const一样(即声明一个T* cosnt指针)——不得指向不同的东西,它所指的东西的值是可以改变的。

const T*指针 => const_iterator

const 可以和函数返回值、各参数、函数自身(成员函数)产生关联

const和non-const成员函数中避免重复

令non-const版本调用const版本可避免代码重复。

class TextBlock {
   
public:
    const char& operator[] (std::size_t position) const
    {
   
        //.....
        return text[position];
    }
    char& operator[] (std::size_t position) {
   
  		return 
            const_cast<char&>( // 返回const对象 转化为非const对象
        static_cast<const TextBlock&>(*this) // 转化为const对象 为调用cosnt函数
        [position]
        );
    }
}

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

C part of C++ 不保证发生初始化

array(来自C part of C++)不保证其内容被初始化, vector(STL part of C++)却有此保证

除内置类型,初始化责任落在构造函数(constructors)身上

别混淆了赋值(assignment)和初始化(initialization)

class PhoneNumber{
    //... };
class ABEntry {
   	// 通讯簿
public:
    ABEntry(const std::string& name, const std::string& address,
           const std::list<PhoneNumber>& phones);
private:
    std::string theName;
    std::string theAddress;
    std::list<PhoneNumber> thePhones;
    int numTimesConsulted;
}// 首先调用default构造函数为theName、theAddress和thePhones设初值
// 然后立即再对他们赋予新值 浪费了default构造函数做的一切
AbEntry::ABEntry(const std::string& name, const std::string& address,
           const std::list<PhoneNumber>& phones);
    {
   
        theName = name; // 这些都是赋值(assignments)
        theAddress = address; // 而非初始化 (initializations)
        thePhones = phones;
        numTimesConsulted = 0; // 内置对象,初始化和赋值的成本相同
    }
AbEntry::ABEntry(const std::string& name, const std::string& address,
           const std::list<PhoneNumber>& phones) // 现在都是初始化
    :theName(name),
	theAddress(address),
	thePhones(phones),
	numTimesConsulted(0)
{
    }

初始化次序:

base classes更早与其derived被初始化

class的成员变量总是以其声明的次序初始化

static对象,其寿命从被构造出来直到程序结束为止

函数内的static对象称为local static对象,其它的static对象称为non-local-static对象

class FileSystem {
   
public:
    std::size_t numDisks() const;
    //...
};
static FileSystem tfs; //预备给客户使用的对象
class Directory {
   
public:
    Directiry(params);
    // ...
};

Directory::Directory(params
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值