《Effective C++学习》学习笔记01-03

Effective C++学习

第0章导读

术语(terminology)

声明式(Declaration):告诉编译器某个东西的名称和类型,但略去细节

extern int x;
std::size_t numDigits(int number);
class Widget;
template<typename T>
class GraphNode;

签名式(Signature):揭示函数的参数和返回类型,std::size_t(int)说明函数numDigit的参数是Int型,返回类型是std::size_t
定义式(Definition):提供编译器一些声明式所漏的细节。被声明为explicit的构造函数比non-explicit兄弟更受欢迎,作者建议除非有特别好的理由允许构造函数被用于隐式转换,建议都加上explicit声明.以组织隐式转换。
初始化(Initialization):给予对象初值
类作为参数传递,最好采用引用类型,而不是pass-by-value
STL是所谓的标准模板库(Standard Template Library),是C++标准程序库的一部分,致力于容器(vector, list, set, map)、迭代器(vector::iterator, set::iterator等等)、算法(for_each, fidn, sort)。建议读者熟悉STL
不明确定义(undefined behavior):野指针、数组索引越界(竭力避免)

int* p = 0;
std::cout << *p;

char name[] = “hello”
char c = name[10]

TR1和BOOST

TR1(Technical Report1):是一份规范,描述加入C++标准程序库的诸多新机能。这些机能以新的class template 和 function template形式体现, 针对的题目有hash table, referencing-consuming,regular expression,所有的TR1组件在命名空间tr1内,后者嵌套与命名空间std内。
boost:是一个组织,同样是一个网站(boost), 提高可移植的、同行评审源码开放的C++程序库。

第1章 让自己习惯C++

条款01 视C++为一个语言联邦(fedreation)

为了了解C++,你必须认识其主要的次语言(sublanguage)。

  • C 说到底,C++仍是以C为基础(blocks, statement, preprocessor, built-in data types, array, pointers)。但是没有templates, exception, overloading
  • objected-oriented C++.包括构造函数,析构函数, 封装(encapsulation), 继承(inheritance)、多态(polymorphism)、virtual函数(动态绑定)
  • templateC++
  • STL

条款02 尽量以const, enum, inline替换#define(宁可以编译器替换预处理器)

#define PI 3.14

编译过程如图:
《Effective C++学习》学习笔记01-03_第1张图片
#define在预处理阶段被预处理器移走, 可能会带来编译错误。
解决办法:

const double PI = 3.14

特殊情况:
如果是字符串常量,则需要两个const,限制指针以及其指向的内容均不可变

const char* const a = "nihao"//第一个const被指物不可变(*左侧),第二个限制指针本身不可变(*右侧)
//上一行代码等同于 char const * const a = "你好"(关键看const的位置和*的位置关系)
//第二种写法(建议)
const std::string autorname("Scott")

如果是class专属常量,按下声明

class GamePlayer
{
private:
	static const int NumTurns = 5;//声明常量式
	int score[numTurns];//使用常量式
}

class专属常量不同于一般常量,一般常量需要给出定义式,专属常量给出声明式就可以使用, 如果必须提供专属常量定义式,按如下定义:

const int GamePlayer::NumTurns;//定义式应该放在实现文件(.cpp),并且不需要再次赋值

enum最大的好处是无法取址以及无法引用,适当的情况下采用enum也可。

class GamePlayer
{
private:
	enumerate{ NumTurns = 5};//声明常量式
	int score[numTurns];//使用常量式
}

函数模板替代宏
参考代码:

typename<typename T>
inline void CallWithMax(const T&a, const T&b)
{
	f(a > b ? a : b);//a和b中的较大值作为参数
}

总结

  • 对于单纯常量,采用const和enum替代#define
  • 对于形似函数的宏,采用inline函数替换#define

条款03 尽可能的用const

char greeting[] = "Hello";
char* p = greeting;  //p和(*p)都不是常量
const char* p = greeting  //(*p)是常量(被指物)
char* const p = greeting  //p是常量(指针本身)
const char* const p = greeting  //p和(*p)都是常量

const在STL中的应用
STL迭代器中的T指针是一个T const指针,也即可以改变*iter的值,但是不能改变iter的值。
如果想要与上述情况相反,则采用const_iterator

std::vector<int> vec;
const std::vector<int>::iternator iter = vec.begin();  //相当于T* const
*iter = 10;  
++iter;  //不可
std::vector<int>::const_iternator cIter = vec.begin();  //相当于const T* 
*iter = 10  //不可
++iter;

cosnt在函数声明式的应用

  • 返回一个const对象(一般是指针类型或者引用类型)

  • const用于成员函数
    成员函数参数采用引用传递或者指针,采用const修饰
    限定不能修改成员变量(除了static类型的)

    如何修改const变量的值?

    const MyString hello("hello");  //MyString是自己定义的一个类
    cout << hello << endl;  //hello
    char* a = &hello[1];  // char& operator[](int n) const;
    cout << "a: " << a << " " << endl; //a:e
    *a = 'l';
    cout << hello << endl;  //hlllo

这就是所谓的logical constness,一个const成员函数可以修改成员变量的某些bits。
使用mutable关键字仍然可以达到上述目的,const成员函数可以在函数实现中更改mutable成员变量。
总结

  • const可用于对象函数参数函数返回类型成员函数本体
  • const成员函数和non-const成员函数有着实质等价的实现时, 让non-const版本调用const版本可避免代码重复。

参考:
预处理器说明
C语言编译过程
Static关键字作用
Const关键字作用

你可能感兴趣的:(C++,effectiveC++)