Effective C++(1)(1~4)

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

四个次语言:

  • C
  • Object-Oriented C++(面向对象C++)
  • Template C++
  • STL

02:尽量以 const, enum, inline代替 #define

使用#define时,编译器“看不到”你所define的变量,那么当报错时,为了查找理解你所定义的,就需要耗费大量时间

#define ASPECT_RATIO 1.653    //aspect_ratio并未进入符号表

当以常量代替#define时,有两种特殊情况

  • 定义常量指针
const char* const authoerNameo = "ScottMeyers"
  • 定义class专有常量
//为了将常量作用域限制于class内,需要static
class GamePlayer{
    static const int NumTurns = 5;//常量声明式
    int scores[NumTurns];//使用常量    
}

对于形似函数的宏(如#definr Test(a,b) f((a)>(b)?(a):(b))),可以用inline代替

template<typename T>
inline void callWithMax(const T& a, const T& b)
{
    f(a > b ? a: b);
}

03:尽可能使用const

const的几种不同用法

char greeting[] = "hewwl";
char* p = greeting;
const char* p =greeting;    //non-const pointer, const data
char* const p = greeting;   //const pointer, non-const data
const char* const p = greeting; //const pointer, const data
//注: const Widget* pw与Widget const* pw等价

令函数返回一个常量值,可以降低因错误而造成的意外,如:

class Rational{};
const Rational operator*(const Rational& lhs, const Rational& rhs);
//如果没有const可能会造成
Rational a,b,c;
if (a*b = c)
{
    /* code */
}

另:双目运算符operator*想拥有两个参数,必须在类外定义,因为类内有隐式this指针

当const 和 non-const成员函数有着实质等价的实现时,令non-const版本调用const版本来避免代码重复

class TextBlock { public: const char& operator[](std::size_t position) const{ //过程1 //过程2 //过程3 return text[position]; } char& operator[](std::size_t position){ return const_cast<char&> (static_cast<const TextBlock&> (*this)[position]); } }; //注:不能用const调用non-const,因为non-const可能改变对象

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

  • 为内置对象进行手工初始化

    内置对象不进行手工初始化的话很可能得到随机值,而浪费性能

  • 构造函数使用成员初始化列表,而不是赋值

 

class A
{
private:
    int member1;
    double member2;
    std::string member3;

public:
    //使用初始值列表
    A() : member1(0), member2(0), member3(std::string()){}
    //赋值初始化
    A(){
        member1 = 0;
        member2 = 0;
        member3 = "";
    }
};

 

  使用赋值初始化的构造函数在赋值前还会调用default的构造函数,因此会造成性能流失

 

  • 以本地静态对象代替非本地静态对象

  这是为避免跨编译单元初始化次序问题而提出的解决方案,简单来说就是:

//a.cpp
class hen{
    public:
    std::size_t makeEggs();
};
hen ji;//non-local static

//b.cpp
extern hen ji;
class eggs{
    public:
    void eggs()
    {
        ji.makeEggs();
    }
};

  此时若调用eggs构造函数,而ji未初始化,则会造成严重问题(多编译文件初始化次序不确定)

  而

//a.cpp
class hen{
    public:
    std::size_t makeEggs();
};
hen& chicken()
{
    static hen ji
    return ji;
};

//b.cpp
extern hen ji;
class eggs{
    public:
    eggs()
    {
        chicken().makeEggs();
    }
};

  不存在问题,原因简单分析:

non-local static 的做法 ——> 调用 eggs 构造函数 ——> 调用 ji.make_egg() ——> 发现 ji对象没有被初始化 —>死亡

local static 的做法 ——> 调用 eggs() ——> 调用 egg 构造函数 ——> 调用 ji() ——> 调用 ji 的构造函数 —> 成功

参考链接

 

posted @ 2022-03-04 22:39  帝皇の惊  阅读(41)  评论(0)    收藏  举报