《Thinking in C++, 2nd Edition》笔记-第十一章(References & the Copy-Constructor)
C++是一种更强类型的语言,比如void*,C中不允许一种类型指针赋值给另一种类型指针,但是可以通过void*来实现:
bird* b; rock* r; void* v; v = r; b = v;而在C++中这种转换必须用显示的类型转换才行。C++中的引用
引用就像是能被编译器自动解引用的指针。
1)引用在创建时必须被初始化。(指针可以在任何时候初始化)
2)引用初始化指向一个对象之后,不能改变为对另一个对象引用。(指针随时可以指向另一个对象)。
3)不可能有NULL引用。引用必须和一块合法存储关联。
函数中的引用
引用在函数的参数和返回值中经常见到,如果函数参数是引用,和指针一样,函数可以改变外界传入的这个参数,如下所示:
// Simple C++ references int* f(int* x) { (*x)++; return x; // Safe, x is outside this scope } int& g(int& x) { x++; // Same effect as in f() return x; // Safe, outside this scope } 11: References & the Copy-Constructor 477 int& h() { int q; //! return q; // Error static int x; return x; // Safe, x lives outside this scope } int main() { int a = 0; f(&a); // Ugly (but explicit) g(a); // Clean (but hidden) }函数的参数为普通引用时,传入的参数不能是常量。如果要传入常量,将函数的参数也改为const引用,如下所示:void f(int&) {} void g(const int&) {} int main() { //! f(1); // Error g(1); }拷贝构造函数传值方式需要调用构造函数和析构函数。在C和C++中,函数调用时会首先将参数压入到栈中(从右到左),当参数是传值时,编译器压入的时参数的一个拷贝。如果是内置的数据类型,那么拷贝是位拷贝,如果是自定义的数据类型而且没有定义拷贝构造函数,会自动生成位拷贝构造函数(不一定正确)。当这个自定义数据类型内部含有指针或数组
类型数据时,位拷贝会出现问题,此时应该手动定义拷贝构造函数。当创建了拷贝构造函数时,就不会发生位拷贝了。
事实上,通常只是对一个类进行传值时才需要定义拷贝构造函数,否则,就不需要拷贝构造函数,所以,如果要防止传值,可以将拷贝函数声明为私有的(不需要定义)。