# C++ pointers 和reference
Date: 2021-10-25


Pointer 和 references

#### **主要区别**

- reference：总代表一个对象， 没有null reference；pointer则没有限制，可以为null
- poiner可以被重新赋值； reference不可以被重新赋值。

#### **应用场景**

如果在不同时间指向不同对象则使用pointer， 如果一旦代表该对象就不能改变选择reference.

#### **相关代码：**

使用reference更富效率, 如下面的例子，不需要测试rd的值，他代表某一个double

```
void printDouble(const double &rd) 
{
   cout << rd;
}
```

而如果用pointers，那么就得测试下他是否为null。

```
void printDouble(const double *pd)
{
  if (pd) {
    cout << *pd;
  }
}
```

 

#### **其他：**

当然也有例外， 比如leveldb中就可以看到一下issue，[DB::Get API should use reference instead of pointer #140](https://github.com/google/leveldb/issues/140)

可以看到在下面一段描述，这里主要讨论关于函数参数使用引用还是指针。

```
Original issue 134 created by jvb127 on 2013-01-03T06:36:56.000Z:

The current DB::Get API is defined as:
virtual Status Get(const ReadOptions& options,
const Slice& key, std::string* value) = 0;

However, 'value' is not an optional parameter - it should point to a valid std::string. This is not checked by the implementation

It could be considered to use a reference rather than a pointer:
virtual Status Get(const ReadOptions& options,
const Slice& key, std::string& value) = 0;
```

可以看到在google早些年的开发指南中，使用指针定义参数列表的参数和引用，通过const区分输入，输出参数。

```
Comment #1 originally posted by jtolds on 2013-01-03T09:21:10.000Z:

as Alexander Melnikov points out on the list, this will likely not get fixed as the Google style guide specifies this way.

see http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Reference_Arguments#Reference_Arguments

tl;dr: google style guide uses pointers for out arguments and references for in arguments
```

- 定义：

[leveldb](https://github.com/google/leveldb)/[include](https://github.com/google/leveldb/tree/master/include)/[leveldb](https://github.com/google/leveldb/tree/master/include/leveldb)/**db.h**

```
// If the database contains an entry for "key" store the
// corresponding value in *value and return OK.
//
// If there is no entry for "key" leave *value unchanged and return
// a status for which Status::IsNotFound() returns true.
//
// May return some other Status on an error.
virtual Status Get(const ReadOptions& options, const Slice& key,
                   std::string* value) = 0;
```

- 如何使用：

```
std::string value;
leveldb::Status s = db->Get(leveldb::ReadOptions(), key1, &value);
if (s.ok()) s = db->Put(leveldb::WriteOptions(), key2, value);
if (s.ok()) s = db->Delete(leveldb::WriteOptions(), key1);
```

虽然传递的是指针，但他指向了一个已经创建的对象。

 

#### **参考及引用：**

More Effective C++ 中文版（35个改善编程与设计的有效方法）

图片 ：[台灣野鳥攝影 Photo-eye 鳥訊](https://www.facebook.com/groups/296994820448873/?hoisted_section_header_type=recently_seen&multi_permalinks=2116121818536155&__cft__[0]=AZWhiUwzuHJ54aoadJA-SilSdc9psyp5t9eHwCWJKXLnEX8_1RMS4tDmPOcjzz9_gA3ZMAMpUf72JcjvmUqxKTyS0th8NBlwh0lMukPBuU_BpzEAXtRMaMCdLsKbQb0U4kjM25ZQXVhffLQqPV8C59clSNu9nFrMnDdnJpQQysD9BYtDVaiH6Y_IJ2KY4F8ZO4c&__tn__=-UC%2CP-R)

