第5.16章: 指针最佳实践

English

概述

在学习了指针如何工作以及需要避免的许多陷阱之后,本章 总结在现代 C++ 中安全、清晰地使用指针的最佳实践。

你将学到:

1. 始终初始化指针

指针应始终初始化为有效对象,或者初始化为 nullptr。


int x{42};
int *p = ::std::addressof(x);   // ✔ good

int *q{};                       // ✔ initialized to nullptr

2. 只读数据使用 T const*

这遵循第2.8章的规则:const 作用于左边。 就这样。


char const *s = "Hello";   // ✔ correct for C-style strings

const 正确性可防止意外修改。

3. 使用 ::std::addressof 而不是 &

& 可以被重载。::std::addressof 总是返回 对象的真实地址。

4. 对迭代器使用 ::std::to_address

::std::to_address 从任何行为类似指针的迭代器中 取出原始指针。


auto it = v.begin();
int *p = ::std::to_address(it);   // ✔ universal pointer extraction

5. 类型双关使用 memcpy 或 ::std::bit_cast

永远不要用 reinterpret_cast 做类型双关。它会违反严格 别名规则(第5.13章)。


float f{1.0f};
std::uint32_t u = ::std::bit_cast<std::uint32_t>(f);   // ✔ safe

6. 不确定是否重叠时使用 memmove

对重叠内存使用 memcpy 是未定义行为。 memmove 始终安全。

7. 调用内存函数之前始终检查 size != 0

用 nullptr 配非零大小调用 memcpy、memmove、 memcmp 或 memchr 是未定义 行为。


if (n != 0) {
    ::std::memcpy(dst, src, n);
}

8. 机密数据使用 ::fast_io::secure_clear

memset 可能被优化掉。 ::fast_io::secure_clear 保证内存确实被擦除。


char secret[32]{};
::fast_io::secure_clear(secret, sizeof(secret));   // ✔ secure

9. 保持指针算术简单

尽可能优先使用索引。避免花哨的指针技巧。

10. 尊重对象的生命周期

指针不会延长它所指向对象的生命周期。

11. 避免 reinterpret_cast

它几乎总是错的。 请改用 memcpy 或 ::std::bit_cast。

12. 尽可能优先使用更高层的抽象

指针很强大但也很危险。请有意识地使用它们,而不是随手使用。

要点