《Effective C++》第一章:让自己习惯C++

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

C++不是一个带有一组守则的一体语言;它是从四个次语言组成的联邦政府,每个次语言都有自己的规约

  • C。说到底C++仍然是以C为基础。区块、语句、预处理器、内置数据类型、数组、指针等都来自C
  • Object-Oriented C++。Classes(包括构造函数和析构函数),封装(encapsulation),继承(inheritance)、多态(polymorphism)、virtual函数(动态绑定)
  • Template C++。C++都泛型编程(generic programming)
  • STL。容器(containers)、迭代器(iterators)、算法(algorithms)以及函数对象(function objects)

2.条款02: 尽量以 const, enums, inlines 替换#difines

#define 定义的常量可能不会被编译器看到,也有可能没有进入记号表(symbol table)内
而解决方法是以一个常量替换上述的宏(#define):

const double AspectRatio = 1.6534; //大写名称通常用于宏

记住:

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

3. 条款03: 尽可能使用const

const 允许你指定一个语义约束。其可以在 classes 外部修饰 globalnamespace 作用域中被声明为 static 的对象。你也可以用它修饰 classes 内部的 staticnon-static 成员变量。面对指针,你也可以指出指针自身、指针所指物,或两者都(或都不)是const

	char greeting[] = "Hello";
	char *p = greeting;  // non-const pointer, non-const data
	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出现在星号左边,表示被指物是常量;如果出现在星号右边,表示指针自身是常量;如果出现在星号两边,表示被指物和指针两者都是常量

STL迭代器作用像个T*指针。声明迭代器为 const 一样,表示这个迭代器不得不指向不同的东西,但它所指的东西的指是可以改动的。如果希望其所指的东西不可悲改动(即希望STL模拟一个const T*指针),则需要的是const_iterator

	std::vector vec;
	const std::vector::iterator iter = vec.begin(); //iter的作用像个T* cosnt
	*iter = 10; //没有问题,改变iter所指物
	++iter; //错误,iter是const
	std::vector::const_iterator cIter = vec.begin(); //citer的作用像个const T* 
	*cIter = 10; //错误,*cIter是const
	++cIter; //没问题

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

永远在使用对象之前先将其初始化,对内置型对象进行手工初始化,因为C++不保证初始化它们。对于内置类型以外的其他东西,初始化责任落在构造函数身上。规则很简单:确保每一个构造函数都将对象的每一个成员初始化。

赋值和初始化容易弄错:

	//赋值版本
	class A {
	public: A(const std::string& name, const std::string& address);
	private:
		std::string theName;
		std::string theAddress;
	}
	A:A(const std::string& name, const std::string& address) {
		theName = name; //这些都是赋值,不是初始化
		theAddress = address;
	}
	//初始化版本
	class A {
	public: A(const std::string& name, const std::string& address);
	private:
		std::string theName;
		std::string theAddress;
	}
	A:A(const std::string& name, const std::string& address):theName(name), theAddress(address) {
	}

基于赋值的版本,首先调用default构造函数为theName,theAddress设初值,然后立刻对其赋予新值。
总结

  1. 成员变量是constreferences,他们就一定需要初值,不能被赋值。
  2. 构造函数最好使用成员初值列(member initialization list),而不要在构造函数本体内使用赋值操作。初值列列出的成员变量,其排列次序应该和它们在class中的声明次序相同

你可能感兴趣的:(C++,c++,开发语言)