问题标签 [copy-and-swap]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
322 浏览

c++ - 有一个抛出交换成员实现可以吗?

编写类时的一般准则(使用复制和交换习惯用法)是提供一个非抛出交换成员函数。(Effective C++,第 3 版,第 25 条和其他资源)

但是,如果因为我的班级使用不提供交换操作的第 3 方班级成员而无法提供 nothrow 保证怎么办?

CString 交换不能不抛出,因此交换失败的可能性很小。

注意:对于罕见的第 3 方课程,可以选择使用智能 ptr (pimpl),但是--

注意:CString 是一个很好的例子,因为他头脑正常(?)的人不会开始通过 pimpl(智能 ptr)持有概念上简单且无处不在的类的所有成员,例如 CString,因为这看起来真的很可怕——另一方面,没有(短期到中期)机会来修改 CString 以允许完全不抛出交换。

那么,如果你不能帮助它,是否可以有一个潜在的抛出交换成员函数?(或者你知道解决这个难题的方法吗?)

编辑:并且:如果不是强保证,是否可以将抛出交换成员与复制和交换习语一起使用以提供基本保证?

0 投票
1 回答
785 浏览

c++ - 引用抽象类的类的复制和交换习语

我正在尝试为我的班级实现Copy-and-Swap Idiom,因为我需要实现operator=,并且由于它具有引用成员,并且引用只能分配一次,所以我认为上述成语是一种有效的解决方法。

但是现在我遇到了构建错误:

它指向我这里:

这是成语中的 Swap 函数,m_Variables确实是对抽象类的引用。交换那种参考是不可能的吗?如果有针对此的 Boost 解决方案,请告诉我,因为我最近开始使用它。

0 投票
2 回答
1781 浏览

c++ - C++ 中用于可变长度记录的无锁共享内存

我是 IPC 的新手。Writer进程将数据写入共享内存,许多Reader进程读取数据。要写入的数据具有唯一标识符,必须通过唯一键索引以便更快地访问(例如 STL::map 或 hashmap 用于查找)。数据也是可变长度记录( XML )(平均长度为 200-250 字节)。操作系统是 Intel Xeon 四核服务器上的 solaris 10 (i86pc)。

总数据量超过200G。但我们将只在共享内存中保留最新数据。历史数据驻留在文件中。共享内存大小约为 4G~6G。

没有像 Boost::interprocess 这样的外部库可用

我有几个问题,可能很多

  1. 哪个更有效:shared_memory 或 mmap(内存映射文件)
  2. 如何为可变长度记录建立索引。[我不知道,可能是一些散列?]。
  3. 如果将 XML 转换为固定大小的结构,这会不会很整洁(权衡结构的大小将是巨大的,近 300 多个可能的字段)
  4. 我们可以通过提供自定义分配器将任何 STL 放在 shared_memory 中吗?
  5. 是否可以在没有信号量的情况下实现(使用 CAS 的无锁实现)。

谢谢

这个怎么样。

当新数据到达并且段已满时。最旧的数据以循环方式擦除。可能需要删除 1 条以上的记录。

0 投票
2 回答
321 浏览

c++ - 通过接口完成复制和交换

我正在尝试实现一个复制+交换习语,以通过一定程度的抽象来实现强异常安全,尽管原理很明确,但通常情况下,魔鬼在细节中。

假设我有一个看起来像这样的类:

我现在可以在只处理 ISomething 的方法中执行此操作:

在哪里

这一切都有效,因为所有 dynamic_casts 都在引用上,这是一个在不支持类型时抛出的操作;这使我的对象处于良好状态,因为交换直到最后才会发生。但我不满意的是,调用 swappable1.Swap(swappable2) 仍然可以抛出(通过相同的 dynamic_cast 机制),这对于 Swap 的用户来说是违反直觉的,因为他可能不会期待任何事情在那个时候扔。

我想到的另一种方法是模板化 ISwappable,以便在 Swap 的实现中取消 dynamic_cast:

所以它的实现很简单

这允许 Swap 调用不被抛出(并允许我保证这两个对象在编译时实际上是可交换的),但现在的问题是我必须处理 DoSomething 中的具体类型,但我没有t 可以访问该函数内的 AConcreteType。

有任何想法吗?

0 投票
4 回答
3296 浏览

c++ - 为 C++ 模板类提供 swap() 会破坏 std::swap()?

我试图在我的自定义 Matrix 类中实现复制和交换习语,但我在以链接到问题中建议的方式实现 swap() 时遇到了一些麻烦:

(我使用的编译器是MS VS2010 IDE的编译器,方言是很好的老式C++03。)

现在我无法在代码中为驻留在此命名空间中的函数访问常规 std::swap() :

不幸的是,由于某种原因,my_space::swap()对于 Matrix 似乎将所有其他调用别名为std::swap(),我不知道为什么因为参数不适合并且 ADL 应该支持std::swap

(对于我尝试使用的每一行,错误都会重复 10 次std::swap

my_space::swap()总是否决std::swap()in my_space,即使论点不合适?它不是std::swap()不可见的,它在my_space::swap()创建之前工作正常。

0 投票
2 回答
2502 浏览

c++ - 在虚拟继承中交换和复制习语的正确方法是什么?

考虑经典的虚拟继承菱形层次结构。我想知道在这种层次结构中复制和交换习语的正确实现是什么。

这个例子有点人为——而且它不是很聪明——因为它可以很好地使用 A、B、D 类的默认复制语义。但只是为了说明问题 - 请忘记示例弱点并提供解决方案。

所以我有从 2 个基类 (B<1>,B<2>) 派生的 D 类 - 每个 B 类实际上都继承自 A 类。每个类都具有使用复制和交换习语的非平凡复制语义。最派生的 D 类在使用这个习语时有问题。当它调用 B<1> 和 B<2> 交换方法时 - 它交换虚拟基类成员两次 - 所以 A 子对象保持不变!!!

A:

丁:

S只是一个存储字符串的类。

进行复制时,您会看到 A::s 保持不变:

结果是:

可能添加B<N>::swapOnlyMe会解决问题:

但是当 B 从 A 私下继承时呢?

0 投票
1 回答
2231 浏览

c++ - 'operator=' 的模棱两可的重载与 c++11 std::move 以及复制和交换习语

我收到以下错误:

编译以下代码时:

编译时g++ -std=c++11 main.cpp && ./a.out

有人可以帮我理解为什么在这种情况下使用复制和交换习语时会出现歧义吗?

0 投票
2 回答
424 浏览

php - 在两个 html 文件之间用 php 交换元素

我有一个我想用 php 解决的问题,但我在 php 编程方面完全是菜鸟问题是,我正在用 jquery 修改一个 html 表,我接下来要做的是交换这个另一个 html 文件中带有另一个精确表的表(某些单元格的类除外)

假设第一个文件名为 scheduleAdmin.html,并且有我想要“转移”到另一个文件(位于同一目录中)的表,名为 schedule.html。这两个文件都有这个带有 id='schedule' 的表。

我相信这对 php 来说是一件容易的事,但我真的没有取得太大进展。

任何帮助将不胜感激

0 投票
3 回答
1393 浏览

c++ - 复制和交换习语效率低下?

我正在测试一些代码,其中类中有一个std::vector数据成员。该类既可复制又可移动,并且按照operator=此处所述使用复制和交换习语实现。

如果有两个vectors,说v1大容量和v2小容量,v2复制到v1( v1 = v2),赋值后保留in中的大容量;v1这是有道理的,因为下一次v1.push_back()调用不必强制进行新的重新分配(换句话说:释放已经可用的内存,然后重新分配它以增加向量并没有多大意义)。

但是,如果对具有as 数据成员的vector进行相同的分配,则行为会有所不同,并且分配后不会保留更大的容量。

如果使用 copy-and-swap 习语,而 copyoperator=和 moveoperator=分开实现的,那么行为就如预期的那样(与普通的 non-member 一样vector)。

这是为什么?我们是否应该不遵循复制和交换习惯,而是分别实现operator=(const X& other)复制 op=)和operator=(X&& other)移动 op=)以获得最佳性能?

这是使用复制和交换习语的可重现测试的输出(请注意,在这种情况下,后 x1 = x2,x1.GetV().capacity()是 1,000,而不是 1,000,000):

这是没有复制和交换习语的输出(请注意在这种情况下如何x1.GetV().capacity() = 1000000,正如预期的那样):

可编译的示例代码如下(用VS2010 SP1/VC10测试):

0 投票
1 回答
1044 浏览

c++ - C ++:复制和交换习语,替代构造函数

注意:这个问题是在上一个问题之后,我希望仍然可以将它作为一个新问题提出。

我正在尝试为树类实现“三个半大规则”(复制和交换习语),如下所示:

我一直在努力遵循这个准则。这是我的复制赋值运算符的样子:

我很难让我的公共构造函数工作。有人建议我这样做:

我不确定这个想法是否有效。在任何情况下,我都会从编译器收到以下错误:

我尝试了以下想法,我认为它会起作用:

但它似乎也不起作用。我认为问题在于,当我调用复制赋值运算符 ( *this = Tree(&aTemp, &bTemp, depth, depth)) 时,应该调用复制构造函数(因为复制赋值运算符的参数是按值传递的),但似乎没有发生这种情况。我不懂为什么。

提前感谢您的帮助!