【发布时间】:2012-07-23 04:59:50
【问题描述】:
在 OOP 语言(包括 C++)中,您不应该将对象指针视为指向原始二进制数据的指针。对象“不仅仅是”它们的表现形式。
因此,例如,swap通过交换两个对象的字节是不正确的:
template<class T>
void bad_swap(T &a, T &b) // Assuming T is the most-derived type of the object
{
char temp[sizeof(T)];
memcpy(temp, &a, sizeof(a));
memcpy(&a, &b, sizeof(b));
memcpy(&b, temp, sizeof(temp));
}
然而,我可以想象这个快捷方式导致问题的唯一情况是当一个对象包含一个指向自身的指针时,我在实践中很少(从来没有?)看到过;不过,可能还有其他情况。
如果执行按位交换,正确的 swap 何时会中断,有哪些实际(现实世界)示例?
我可以很容易地想出带有自指针的人为示例,但我想不出任何真实世界的示例。
【问题讨论】:
-
这对于可简单复制的类型是完全合法的。 C++ 不是严格意义上的“OOP 语言”,可平凡复制的类型不“不仅仅是它们的表示”。
-
什么时候是一个好的主意?我敢肯定,只要二进制副本或交换正常,编译器就会生成它。
-
使用指向自身的指针的常用对象是 std::string,为了优化,一些实现包含一个短字符串缓冲区,它是主“结构”的一部分。如果长度超出此缓冲区的大小,则使用动态分配的缓冲区。有一个指针,要么指向内部短字符串,要么指向动态分配的缓冲区。
-
我不知道您使用的是什么编译器,但我看到的编译器足够聪明,可以内联
memcpy,并为结构分配(或循环)生成相同的代码复制一个数组)。 -
请注意,交换自指针的问题不仅影响具有自指针的对象,还影响包含此类对象的任何其他对象。
标签: c++ bit-manipulation swap