More Effective C++ 条款1
程序员文章站
2022-07-12 17:54:58
...
条款1:仔细区别pointers和references
1、没有所谓的空引用
引用必须绑定某个对象,所以当我们设计的对象不能为null时,可以用引用来绑定这个对象。相反如果设计的对象可以为null时,应该使用指针去绑定这个对象,因为指针可以设为null。
这一规定意味着使用引用会比指针更高效,因为一般在使用指针之前通常需要去判断指针是否为空,而引用就不用考虑这些烦人的问题了。
void printData(const int &data)
{
cout << data << endl; // 不需要判空
}
void printData(const int *data)
{
if (data != nullptr) { // 需要检查是否为空指针
cout << *data << endl;
}
}
2、引用必须有初值
由于引用一定得代表一个对象,所以引用必须有初值,相反指针就没有这样的限制。
int &ref; // 错,引用必须初始化。
int data = 0;
int &ref = data; // 对,ref绑定data。
int *ptr; // 指针可以不初始化,但建议不要这样写,因为此时ptr为任意值,它可能指向一段重要的代码,
// 如果我们修改ptr指向的内存中的内容,会很危险,这也是野指针的一种。
3、永久绑定
指针和引用另一个重要的区别就是,指针可以重新赋值,可以指向另一个对象,而引用永远只能指向最初所绑定的那个对象。
string s1 = "hello";
string s2 = "world";
string &ref = s1; // ref指向s1
string *ptr = s1; // ptr指向s2
ref = s2; // ref仍然指向s1,但此时s1的值变为了"world"
ptr = &s2; // ptr现在指向了s2
4、使用某些操作符的情况
当我们实现某些操作符时,也需要使用引用,最常见的就是operator[]。
vector <int> v(10); // int型vector
v[0] = 0; // 赋值对象是operator[]的返回值,即引用。
*v[0] = 0; // 如果返回的是一个指针,则赋值操作必须这样写。
总结:当我们知道需要指向某个东西,且绝对不会再去指向其他东西,或是实现的操作符,其语法需求用指针无法实现,我们就应该选用引用。而其他任何情况,需要用指针。
推荐阅读
-
Effective C++ 笔记:条款 31 将编译关系降至最低
-
More Effective C++在leveldb中的体现
-
Effective Modern C++ 条款32 对于lambda,使用初始化捕获来把对象移动到闭包
-
Effective Modern C++ 条款23 理解std::move和std::forward
-
Effective Modern C++ 条款37 在所有路径上,让std::thread对象变得不可连接(unjoinable)
-
Effective Modern C++ 条款38 意识到线程句柄的析构函数的不同行为
-
Effective C++ chapter1:Accustiming Yourself to C++
-
Effective Modern C++ 条款22 当使用Pimpl Idiom时,在实现文件中定义特殊成员函数
-
Effective C++ 笔记:条款 33 避免继承导致的名称遮掩
-
Effective C++:条款26:尽可能延后变量定义式的出现时间