问题标签 [copy-assignment]

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 投票
1 回答
80 浏览

c++ - 不在复制分配运算符中检查对象是否分配给自身真的安全吗?

这是我发现的实现“三法则”的示例:

正如您在上面看到的,复制赋值运算符中的检查被删除,因为创建局部变量然后删除成员指针并将其分配给局部变量。但是,如果我写,我最重要的是:

我分配a1给自己这是否意味着a1'vals被删除,然后a在复制分配运算符中分配了本地?这是正确的方法吗?我的代码有一些陷阱吗?

  • 任何提示,建议都非常感谢。
0 投票
1 回答
642 浏览

c++ - 如何在没有复制赋值运算符的情况下交换两个对象?

我有一个 A 类,其中删除了复制赋值运算符。我应该如何交换 A 的两个实例?

我尝试使用std::swap,但没有奏效。

我期待obj1并被obj2交换。最初obj1.ais10obj2.ais 20,我希望在完成obj1.a后成为20并且obj2.a将会成为10

0 投票
2 回答
1442 浏览

c++11 - 新的现代 C++ 容器中的分配器传播策略

在容器中具有这些特征的原因是什么(https://en.cppreference.com/w/cpp/memory/allocator_traits

我了解容器实现在分配和交换的实现中将以一种或另一种方式表现。(并且处理这些情况是可怕的代码。)我也明白,有时可能需要将移动容器留在一个状态,resizeble或者至少可以调用一些最后的释放,所以分配器不能无效。(我个人认为这是一个弱论点。)

但问题是,为什么这些信息不能成为自定义分配器类型本身的正常实现和语义的一部分?

我的意思是,容器复制分配可以尝试复制分配源分配器,如果该语法复制分配没有真正复制,那么,就像说你的容器没有 propagate_on_container_copy_assignment

以同样的方式,而不是使用is_always_equalone 实际上可以使分配器分配什么也不做。

(此外,如果is_always_equal是真的,可以让operator==分配器返回std::true_type信号。)

在我看来,这些特征似乎试图覆盖人们可以通过普通 C++ 手段赋予自定义分配器的语义。这似乎与泛型编程和当前的 C++ 哲学背道而驰。

唯一的原因,我认为这对于实现与“旧”容器的某种向后兼容性很有用。

如果我今天要编写一个容器和/或一个的非平凡分配器,我可以依赖分配器的语义而忘记这些特征吗?

在我看来,只要移动的分配器可以“解除分配”一个空指针状态(这意味着在这种特殊情况下基本上什么都不做),那么它应该没问题,如果resize抛出,那也没问题(有效) ,它只是意味着分配器不再有权访问它的堆。


编辑:实际上, 我可以这样简单地编写容器吗?并将复杂性委托给自定义分配器的语义?:

我认为对分配器的唯一真正要求是,从分配器移出的分配器应该能够做到这一点。

并且,如果移出容器由于移出分配器失去对堆的访问权而无法调整大小(例如,因为没有特定资源的默认分配器),那么,太糟糕了,那么操作将抛出(因为任何调整大小可以扔)。

0 投票
1 回答
358 浏览

c++ - 为什么对引用的赋值使用复制赋值运算符?

对于以下示例:

我得到结果:

为什么在将对象分配给引用时使用复制分配?为什么引用没有更新为指向分配的对象?这是惯例问题还是背后有原因?

0 投票
0 回答
19 浏览

c++ - 未选择复制作业

给定以下代码片段,为什么没有选择复制赋值运算符?

它不会编译抱怨复制构造函数被删除。我尝试使用用户声明的赋值运算符,但它仍然不起作用。所以这不是一个隐含的生成规则被打破(这会阻止=default工作)。

这是一个godbolt示例:https ://godbolt.org/z/MkZuGs

我尝试了几个编译器。我的猜测是,声明必须调用复制构造函数,但我只是不明白如何或为什么。

0 投票
1 回答
362 浏览

c++ - CRTP & 复制/移动赋值/构造函数继承

我正在尝试在使用 CRTP 的派生类的基类中实现移动/复制赋值运算符和构造函数。

编译器给我一个错误,说derived& derived::operator=(const derived&)不能用derived& base<derived>::operator=(const derived&). 我的理论是,它以某种方式derived::operator=被隐式定义,然后通过声明引入base<derived>::operator=using试图重新定义它可能吗?这看起来与意外定义方法两次时出现的错误非常相似。

我用 GCC 编译了这个,完整的日志是:

这甚至可以实现,还是我必须在derived类中定义运算符/构造函数,然后将它们的功能委托给base定义中的类?

更新

好吧,也许在用更清晰的头脑看这个之后,它似乎过于复杂。我可以做到以下几点:

所以返回的类型对于每个派生类都是正确的,并且复制是从基类执行的——只复制基本属性,这是我默认需要的。如果我需要更多,那么它特定于每个派生类:

但是,这是一个有趣的练习,关于编译器错误的问题仍未得到解答。

0 投票
3 回答
119 浏览

c++ - 为什么 GCC 在复制赋值操作中拒绝 const 引用?

我想正常重载一个常见的复制赋值运算符。一开始我使用了一个只需要对源进行 const 引用的接口,并显式禁用了接受可修改引用的接口,但我无法通过编译。编译器报告“错误:使用已删除的函数 'ClassA& ClassA::operator=(ClassA&)”

当然,如果我不明确删除接口,我可以编译,但这不是我的目的。我想明确删除它,以避免意外使用它。

为什么复制赋值操作需要对源的可修改引用,而不是 const 引用?赋值操作只需要以只读方式访问源!

关于复制构造函数也有同样的问题,为了简化我省略了它。

我的代码有什么问题?或者我们不能删除它?

我的示例代码如下:

0 投票
3 回答
311 浏览

c++ - 理解和使用复制赋值构造函数

我试图了解复制赋值构造函数在 C++ 中是如何工作的。我只使用过java,所以我真的不在我的水域。我已经阅读并看到返回参考是一个很好的做法,但我不明白我应该如何做到这一点。我写了这个小程序来测试这个概念:

主.cpp:

测试.h:

测试.cpp:

我似乎无法理解我应该在里面放什么operator=()。我见过人们回来*this,但从我读到的只是对对象本身的引用(在左侧=),对吧?然后我考虑返回const Test& t对象的副本,但是使用这个构造函数没有意义吗?我要返回什么,为什么?

0 投票
2 回答
158 浏览

c++ - 具有用户定义指针成员的对象的赋值运算符

我正在尝试在 C++ 中为一个对象实现一个 operator=,该对象具有一个指向用户定义类型的指针作为成员,该类型也分配了动态内存。

因此,鉴于下面的代码,如何为 B 实现正确的 operator=?我所追求的是如何将 A 中的动态内存复制到新的 B 对象中?

任何帮助将非常感激。

谢谢

0 投票
3 回答
21723 浏览

c++ - free():在 C++ 的 tcache 2 中检测到双重释放

首先,我真的检查了是否有问题已经被问过,但我找不到任何问题。错误消息不应该欺骗你我猜我的情况有点不同,或者我只是错过了一些东西。

当我处理一个玩具 C++ 代码时,我遇到了一个奇怪的错误。程序输出说有双重释放的情况,但我看不到这个错误发生的地方。代码可能有点长,对此我深表歉意。

我现在正在工作Linux Distribution,我正在使用g++ 9.1.0. 我检查了我的代码并寻找错误的部分。

即使我修复了部分代码,但我的问题并没有得到解决,除非我评论或者Foo{1, "Hello World"};vec.push_back(std::move(Foo{}));不明白为什么。

如果我不在函数 main 中的任何地方注释,输出如下。

如果我评论 "Foo{1, "Hello World"};",输出变为

最后,当我评论“vec.push_back(std::move(Foo{}));”时,输出变为