问题标签 [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.
c++ - 何时调用复制赋值运算符?
当我阅读复制构造函数和复制赋值构造函数时,我的理解是两者都将它们的属性相互传递,并且它们都是由编译器隐式声明的(如果未定义)。因此,无论是否做有用的事情,两者都必须存在。
然后我测试了这段代码:
但似乎根本没有调用复制赋值运算符。我尝试了三个条件:
一切都包括在内。它打印出来:
/li>Whitout 复制赋值运算符只是复制构造函数。它打印出来:
/li>Whitout 复制构造函数只是复制赋值运算符。它打印出来:
/li>只有构造函数。它打印出来:
/li>
因此,就好像编译器甚至不在乎我是否定义了复制赋值运算符。上面的四个示例都没有打印出“复制赋值运算符”。那么它是什么时候被调用的,如果它真的存在并且有意义呢?
c++ - 我可以为一个类编写复制和移动赋值运算符吗?
这些是我的原型,
但是当我打电话
, 有错误。
编译器返回:
c++ - 是否有正当理由不从复制赋值运算符返回 *this?
让我们foo
成为一个带有复制赋值运算符的结构或类:
除了*this
从operator=()
. _ _ 将其用于与分配无关的事情并不明智。
c++ - 传递分配时安全一些内存
我是 C++ 的新手(来自 C#),我想从一开始就得到那些记忆的东西。
在下面的片段中,一个类型的变量WorldChunkCoordinates
按值传递给内联构造函数,WorldChunk
然后将传递的坐标分配给WorldChunk::Coordinates
,我相信这也是一个复制操作。
(复制分配操作?)
如果我的假设是正确的,那么这会有点愚蠢,因为我复制了两次实例。我认为如果我通过值传递并通过引用指针分配会更好。但是WorldChunk::Coordinates
既不是指针也不是引用。
有没有办法保护我的程序免于复制实例两次?
如果是这样,怎么做?
另外:默认情况下分配 by = 总是一个复制操作吗?
并且:我怎么知道一个特定的类可能有另一个通过引用复制的复制分配操作?
c++ - 智能指针类的线程安全复制赋值运算符
我正在实现一个智能指针类,并且有一些困惑。如果人们可以帮助我澄清,我将不胜感激。
1:我认为智能指针类在构造函数中应该有“new”,在析构函数中应该有“delete”。但是我似乎找不到放置“新”的地方......所以用户将负责创建新的,而智能指针类有助于清理它?
2:在设计复制赋值运算符时,一种流行的方法是复制-n-交换以保证线程安全。但是,copy-n-swap 要求对象按值(而不是按引用)传入。它仍然可以用于设计智能指针吗?我担心这是一个指针类,因此可能无法按值传递。但我对此不太确定。
3:如果我被要求在面试时编写智能指针,我是否必须提供某种类型的引用计数?认为引用计数特定于 shared_ptr ...
4:这一定是个愚蠢的问题,但最好问而不是在心里怀疑。为了SmartPointer<T>& sp
访问ptr,它应该使用sp->ptr
还是sp.ptr
??
感谢您的意见。
c++ - 生成的复制和移动操作符?
目前我正在阅读Scott Meyers的《 Effective Modern C++ 》一书,现在我在:第 17 条:理解特殊成员函数生成。
我的误解来自以下部分(理由):
这两个复制操作是独立的:声明一个不会阻止编译器生成另一个。因此,如果您声明了一个复制构造函数,但没有复制赋值运算符,然后编写需要复制赋值的代码,编译器将为您生成复制赋值运算符。同样,如果您声明了一个复制赋值运算符,但没有复制构造函数,但您的代码需要复制构造,编译器将为您生成复制构造函数。这在 C++98 中是正确的,在 C++11 中仍然是正确的。
这两个移动操作不是独立的。如果您声明其中一个,则会阻止编译器生成另一个。基本原理是,如果你为你的类声明一个移动构造函数,你就表明应该如何实现移动构造,这与编译器生成的默认成员移动不同。如果成员移动构造有问题,那么成员移动分配也可能有问题。因此,声明移动构造函数可防止生成移动赋值运算符,而声明移动赋值运算符可防止编译器生成移动构造函数。
我认为基本原理部分也可以应用于复制构造函数和复制赋值运算符对,不是吗?因此,如果我声明一个复制构造函数,我会用它表明默认的成员复制对我来说是不够的。如果我这么说,那么复制赋值运算符也应该是用户定义的。
我认为这是一本很棒的书,但在这一点上,我还不清楚这个理由。请帮我解释一下。谢谢。
c++ - 填充插入() - 复制构造函数和复制赋值 noexcept 状态?
- STL 容器元素是否需要具有
noexcept
复制构造函数和复制赋值运算符?如果可能,请提供参考。 - 如果不是,当在多插入期间发生异常时,STL 容器的状态是什么,例如在填充插入期间。
尝试编写允许拦截/否决修改的通用包装器时会出现问题。我能想到的任何实现都可能会改变底层容器的语义,除非专门针对每种容器类型(这不是一个真正的选择)。
例如,std::vector
有一个填充插入:
这需要value_type
同时是CopyInsertable和CopyAssignable。请注意,它不需要值类型为DefaultConstructible。
编辑 3 Stroustrup本人(第 956 页上的表格)表示多元素插入应该对所有向量、双端队列、列表和映射都有强有力的保证。这意味着完整的标准库操作会自动成功或失败。
编辑 4但是,该保证仅适用于相关操作(在本例中为复制构造函数)本身不引发异常的情况,这正是我的问题。
据我了解,这留下了两种基本的实现方法:
- 为新元素创建虚拟
val
条目并复制分配。这仅在可以通过复制容器中的现有元素或DefaultConstructible(这不是必需的)value_type
来创建虚拟元素时才有效。 - 一个接一个地复制构造元素到容器中它们各自的位置。这似乎或多或少是规范的实现。
编辑 2:我不会将此称为未定义行为,因为该术语似乎使人们认为未定义为由语言运行时/标准定义。
当复制构造函数或复制赋值运算符引发异常时,这两种实现似乎都会使容器留下未知内容(即不清楚容器在异常之后包含哪些元素)。
编辑 1:请注意,这并不意味着我认为 C++ 运行时存在不良行为,例如内存泄漏或未定义的值。但是,似乎或多或少没有说明容器的内容是什么。特别是,容器的内容可能已经完全(尽管始终如一地)改变。
例如,考虑第三种(混合)方法:
- 创建
n
模板对象的副本列表val
。 - 将此列表中的元素复制分配到目标容器中。
不同之处在于复制构造函数引发异常时对容器的影响。在这种情况下,如果复制构造函数抛出,容器的内容将保持不变(但当复制赋值运算符抛出时仍会导致未指定的内容)。使用指针时(即不使用时std::vector
),复制赋值可能会被忽略,只有指针重新排列,从而使操作原子化。例外。
至于noexcept
容器元素:对象是通过创建的allocator_traits<value_type>::construct(ptr, args)
,这不是noexcept
,我也找不到容器元素大多数具有noexcept
复制构造函数/复制分配运算符的要求(例如std::shared_ptr
,std::unique_ptr
需要这个)。
请注意,复制构造和复制分配的自动生成操作必须是noexcept
,除非它们需要调用本身可能引发异常的操作。
这让我感到困惑,我确定我错过了一些东西,但我无法弄清楚标准中可能证明我错了的部分。
c++ - 为什么在使用 copy-assign 运算符时需要删除资源?
例如,我的一本书中的这样的代码:
似乎 operator= 的内部可能只是:
无需先删除指针,这样做似乎是多余的。它确实提到它的编写方式是在发生异常时使对象处于合适的状态,但没有透露过去,但我看不出会发生什么异常,即使我的替代方案也无法处理。为什么在分配之前需要先删除对象?
c++ - 动态内存分配、指针成员和析构函数
我编写了以下虚拟类来了解复制构造函数、复制赋值运算符和析构函数的工作原理:
我在我的代码中使用这个类类型来测试它是如何工作的,但我正在考虑销毁具有内置指针类型成员的对象的含义:
该指针在构造函数中初始化为指向空闲存储区(始终是新的)动态分配的内存。因此,当调用析构函数时,要销毁的对象的成员以相反的顺序被销毁。在这种情况下,只有 int 和指针对象被破坏,我最终会出现内存泄漏(堆上的字符串没有被释放),这对吗?
而且,定义了这个拷贝赋值操作符,我每次赋值对象时是否都会发生内存泄漏(指针指向堆上的一个新对象而前者丢失了不是吗?)?
c++ - 删除复制构造函数和复制赋值运算符。其中哪些是必不可少的?
我有一个用例,不能以任何方式复制我的对象。我在下面写了一个夸大的复制构造函数和复制赋值运算符删除的完整列表。它们太多了,我无法确定要使用哪些,有时这让我很偏执。我不必将它们全部写在我的代码中,是吗?那么,为了防止任何类型的对象复制,我应该使用哪一个?