1
24
对于大多数类,默认交换是可以的,但是,在所有情况下,默认交换并不是最佳的。最常见的例子是使用 Pointer to Implementation 成语。在默认交换中,大量的内存将被复制,您是专门的交换吗,您只需交换指针就可以显著加快速度。 如果可能,它不应该是类的朋友,但是它可能需要访问私有数据(例如,原始指针),您的类可能不想在类API中公开这些数据。 |
2
23
std::swap()的标准版本适用于大多数可分配的类型。
但它不是最佳实现,因为它调用复制构造函数,然后调用两个赋值运算符。 通过为类添加自己的std::swap()版本,可以实现swap()的优化版本。 例如std::vector。上面定义的默认实现将非常昂贵,因为您需要复制整个数据区域。可能会释放旧的数据区域或重新分配数据区域,并为每个复制的项上包含的类型调用复制构造函数。专用版本有一个非常简单的方法来执行std::swap()。
因此,如果您的类可以优化swap()操作,那么您应该这样做。否则将使用默认版本。 我个人喜欢将swap()实现为非抛出成员方法。然后提供std::swap()的专门版本:
|
3
17
如果您想交换(例如)两个向量而不知道它们的实现,那么基本上您必须这样做:
如果
但是,如果swap函数知道并能够访问向量的内部,那么可能会有一个更有效的实现:
在这个实现中,只需要复制一些指针,而不是像第一个版本中那样的所有元素。因为这个实现需要访问向量的内部,所以它必须是一个友元函数。 |
4
10
我把你的问题解释为基本上三个不同的(相关的)问题。
支持STL的班级需要的原因
这部分问题已经有很多(好的)答案了。基本上,经常了解类的内部结构可以让您编写更优化的
STL算法总是将交换称为自由函数。所以它需要作为一个非成员函数来使用。
基本上,它没有 有 要成为朋友,但如果不需要成为朋友,通常也没有理由实现自定义交换。 注意,您应该确保自由函数与类在同一个名称空间内,这样STL算法可以通过Koening查找找到您的自由函数。 |
5
9
swap函数的另一个用途是帮助异常安全代码: http://www.gotw.ca/gotw/059.htm |
6
2
要实现分配运算符:
这是异常安全的,传递值时通过复制构造函数进行复制,传递临时(通过 copy elision ) |
7
1
效率: 如果有一个类持有(智能)指向数据的指针,那么交换指针可能比交换实际数据更快——3个指针副本对3个深度副本。 如果您使用“using std::swap”+一个非限定的交换调用(或者只使用一个限定的boost::swap调用),那么ADL将使用自定义交换函数,允许编写有效的模板代码。 安全性: 指针交换(原始指针、std::auto_ptr和std::tr1::shared_ptr)不会引发,因此可以用于实现非引发交换。非抛出交换使编写提供强异常保证(事务性代码)的代码更加容易。 一般的模式是:
至于它是否应该作为朋友来实现,交换通常需要了解实现细节。使用一个调用成员函数的非朋友还是使用一个朋友,这是一个品味问题。 问题: 自定义交换通常比单个分配快,但单个分配总是比默认的三个分配交换快。如果你想移动一个对象,就不可能用泛型的方式知道交换或赋值是否是最好的——C++ +0x用移动构造函数解决的问题。 |
Julia · 矢量中相加为总和S的值的数量 1 年前 |
C_Rod · 在模板方法中确定STL容器中项目的数据类型 2 年前 |
quantumwell · 将空向量放入std::map() 6 年前 |
OutOfBound · 对未初始化内存使用算法的优点 6 年前 |
DarthRubik · 在使用列表删除之后,迭代器如何不无效 6 年前 |