Effective C++ 2021-01-14

导读

所谓声明式(declaration)是告诉编译器某个东西的名称和类型(type),但略去细节。

定义式(definition)的任务是提供编译器一些声明式所遗漏的细节。

对对象而言,定义是编译器为此对象拨发内存的地点。对function或function template而言,定义式提供了代码本体。对class或class template而言,定义式列出它们的成员。

初始化(initialization)是“给予对象初值”的过程。

“=”语法也可以来调用copy构造函数。

Widget w3 = w2;    //调用copy构造函数。

以值传递时也是通过copy构造函数完成。

STL是所谓标准模板库(Standard Template Library),是C++标准程序库的一部分,致力于容器(如vector,list,set,map等等)、迭代器(如vector<int>::iterator,set<string>::iterator等等)、算法(如for_each,find,sort等等)及相关机能。

TR1和Boost

TR1(“Technical Report 1”)是一份规范描述加入C++标准程序库的诸多新机能。所有TR1组件都被置于命名空间tr1内,后者嵌套于命名空间std内。

 

1.让自己习惯C++(Accustoming Yourself to C++)

条款01:视C++为一个语言联邦(View C++ as a federation of languages.)

 C++ = C、Object-Oriented C++、Template C++、STL。

请记住:

  • C++高效编程守则视状况而变化,取决于你使用C++的哪一部分。

条款02:尽量以const,enum,inline替换#define(Prefer consts, enums and inlines to #defines)

#define PI 3.14    //未进入记号表

const double PI = 3.14;    //进入记号表
class A {
 public:
  static const int a = 5;    //常量声明式
};
const int A::a;    //a的定义,已设初值不可再设初值

对于“class专属常量+static+整数类”,只要不取它们的地址,可以声明并使用而无须提供定义式。

一个属于枚举类型的数值可权充ints被使用。

class A {
  enum { Numturns = 5; }
  int scores[Numturns];
};

取enum地址不合法,可以实现访问约束。

Enums和#defines一样绝不会导致非必要的内存分配。

Template inline函数代替宏。

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

请记住:

  • 对于单纯常量,最好以const对象或enums替换#defines。
  • 对于形似函数的宏(macros),最好改用inline函数替换#define。

 

条款03:尽可能使用const(Use const whenever possible.)

char str[10] = “hello”;
char *p = str;
const char *p = str;
char const *p = str;
char * const p = str;
const char * const p = str;

STL迭代器的作用就像个T *指针。

const std::vector<int>::iterator iter = vec.begin();  //iter的作用像个T * const
std::vector<int>::const_iterator cIter = vec.begin();  //cIter的作用像个const T *

const成员函数不可以更改对象内任何non-static成员变量。而mutable释放掉non-static成员变量的bitwise constness约束。

class A {
 public:
  const char & operator[](std::size_t pos) const
  { return str[pos]; }  //const对象
  char & operator[](std::size_t pos)
  { return str[pos]; }  //non-const对象
  …
}
char& operator[](std::size_t pos) {
  return const_cast<char&>(static_cast<const A&>(*this)[pos]);
}

non-const版本可以调用const版本,反之不行。

请记住:

  • 将某些东西声明为const可帮助编译器侦测出错误用法。Const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
  • 编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性”(conceptual constness)
  • 当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。

 

条款04:确定对象被使用前已先被初始化(Make sure that objects are initialized before they’re used.)

A(int a) {
  num = a;  //是赋值(assignment)而非初始化(initialization)
}

C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前。

C++固定成员初始化次序,base classes早于derived classes被初始化,而class的成员变量总是以其声明次序被初始化。

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

请记住:

  • 为内置型对象进行手工初始化,因为C++不保证初始化它们。
  • 构造函数最好使用成员初始化列表,而不要在构造函数本体内使用赋值操作(也不是绝对的,如成员变量的初值是从文件或数据库读入)。成员初始化列表次序应该和它们在类中声明次序相同。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值