C++中的指针
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++中,函数调用时会首先将参数压入到栈中(从右到左),当参数是传值时,编译器压入的时参数的一个拷贝。如果是内置的数据类型,那么拷贝是位拷贝,如果是自定义的数据类型而且没有定义拷贝构造函数,会自动生成位拷贝构造函数(不一定正确)。当这个自定义数据类型内部含有指针或数组
类型数据时,位拷贝会出现问题,此时应该手动定义拷贝构造函数。当创建了拷贝构造函数时,就不会发生位拷贝了。
事实上,通常只是对一个类进行传值时才需要定义拷贝构造函数,否则,就不需要拷贝构造函数,所以,如果要防止传值,可以将拷贝函数声明为私有的(不需要定义)。