标签: copy-assignment

在复制操作员方面或单独实施copy-ctor?

这不是根据operator =实现复制构造函数的重复,而是一个更具体的问题.(或者我喜欢思考.)

介绍

鉴于这样的(假设的)类:

struct FooBar {
  long id;
  double valX;
  double valZ;
  long   valN;
  bool   flag; 
  NonCopyable implementation_detail; // cannot and must not be copied

  // ...
};
Run Code Online (Sandbox Code Playgroud)

我们无法通过默认生成的函数复制它,因为您既不能复制构造也不能复制NonCopyable对象.但是,这部分对象是我们实际上对复制不感兴趣的实现细节.

为此编写交换函数没有任何意义,因为交换函数可以复制std :: swap的作用(减去NonCopyable).

因此,如果我们想要复制这些对象,我们就会自己实现copy-ctor和copy-operator.只需分配其他成员即可完成.

如果我们需要实现copy ctor和operator,我们是应该根据copy运算符实现copy ctor,还是应该用初始化列表"复制"代码?

那是,给定:

FooBar& operator=(FooBar const& rhs) {
  // no self assignment check necessary
  id = rhs.id;
  valX = rhs.valX;
  valZ = rhs.valZ;
  valN = rhs.valN;
  flag = rhs.flag;
  // don't copy implementation_detail
  return *this;
}
Run Code Online (Sandbox Code Playgroud)

我们应该写一个)

FooBar(FooBar const& …
Run Code Online (Sandbox Code Playgroud)

c++ copy-assignment

4
推荐指数
1
解决办法
345
查看次数

在C++中,采用基类的构造函数是否算作复制构造函数?

例如:

class Derived : public Base
{
    Derived(const Base &rhs)
    {
        // Is this a copy constructor?
    }
    const Derived &operator=(const Base &rhs)
    {
        // Is this a copy assignment operator?
    }
};
Run Code Online (Sandbox Code Playgroud)
  1. 显示的构造函数是否算作复制构造函数?
  2. 赋值运算符是否显示为复制赋值运算符?

c++ inheritance copy-constructor copy-assignment

4
推荐指数
1
解决办法
153
查看次数

我可以为QObject的子类复制构造函数吗?

在这里,我们可以读到没有复制构造和复制赋值运算符可评估.但是在这里我们可以阅读它,qRegisterMetaType并且Q_DECLARE_METATYPE必须有公共默认构造函数,公共复制构造函数和公共析构函数.问题是:谁说谎?或者我没有正确理解它?

c++ qt copy-constructor moc copy-assignment

4
推荐指数
1
解决办法
3345
查看次数

了解和使用副本分配构造函数

我试图了解副本分配构造函数在c ++中的工作方式。我只使用过Java,所以我真的不在这里。我已经阅读并看到返回引用是一种很好的做法,但是我不知道该怎么做。我写了这个小程序来测试这个概念:

main.cpp:

#include <iostream>
#include "test.h"

using namespace std;

int main() {
    Test t1,t2;
    t1.setAge(10);
    t1.setId('a');
    t2.setAge(20);
    t2.setId('b');

    cout << "T2 (before) : " << t2.getAge() << t2.getID() << "\n";

    t2 = t1; // calls assignment operator, same as t2.operator=(t1)

    cout << "T2 (assignment operator called) : " << t2.getAge() << t2.getID() << "\n";

    Test t3 = t1; // copy constr, same as Test t3(t1)

    cout << "T3 (copy constructor using T1) : " << t3.getAge() << t3.getID() << …
Run Code Online (Sandbox Code Playgroud)

c++ copy-assignment

4
推荐指数
1
解决办法
113
查看次数

Ruby中的对象赋值

来自c ++背景我很好奇Ruby中的对象赋值.应对以下对象分配进行哪些考虑(如果有):

class MyClass

  attr_accessor :a, :b

  def initialize(a, b)
    @a = a
    @b = b
  end

  def some_method
    puts "#{self.a} #{self.b}"
  end
end

m = MyClass.new("first", "last")
n = MyClass.new("pizza", "hello")

q = n
q.some_method
Run Code Online (Sandbox Code Playgroud)

ruby object instance-variables copy-assignment

3
推荐指数
1
解决办法
3609
查看次数

将对象复制到D中的赋值中吗?

当我在D中分配一个对象时,它会被复制吗?

void main() {
    auto test = new Test(new Object());
    tset.obj;
}

class Test {
    public Object obj;

    public this(Object ref origObj) {
        obj = origObj; // Will this copy origObj into obj, or will origObj and obj point to the same data? (Is this a valid way to pass ownership without copying the object?)
    }
}
Run Code Online (Sandbox Code Playgroud)

d reference ownership copy-assignment

3
推荐指数
1
解决办法
313
查看次数

fill insert() - 复制构造函数和复制赋值noexcept状态?

  1. STL容器元素是否需要具有noexcept复制构造函数和复制赋值运算符?如果可能,请提供参考.
  2. 如果不是,当多插入期间发生异常时,例如在填充插入期间,STL容器的状态是什么.

尝试编写允许拦截/否决修改的通用包装时会出现问题.我能提出的任何实现都可能会改变底层容器的语义,除非专门针对每个容器类型(这不是一个真正的选项).

例如,std::vector有一个填充插入:

void insert (iterator position, size_type n, const value_type& val);
Run Code Online (Sandbox Code Playgroud)

这需要value_type同时是CopyInsertableCopyAssignable.需要注意的是它并没有要求值类型为缺省构造.

编辑3 Stroustrup本人(第956页的表)表明多元素插入应该对所有向量,双端队列,列表和映射具有强大的保证.这意味着完整的标准库操作要么原子成功要么失败.

编辑4但是,保证仅适用于相关操作(在本例中为复制构造函数)本身不会抛出异常,这正是我的问题.

据我了解,这留下了两个基本的实现方法:

  1. 为新元素和复制分配创建虚拟条目val.这只有在可以通过复制容器中的现有元素或者何时value_typeDefaultConstructible(这不是必需的)创建虚拟元素时才有效.
  2. 复制构造元素一个接一个地直接进入容器中它们各自的位置.这似乎或多或少是规范的实现.

编辑2:我不会调用这种未定义的行为,因为该术语似乎会使人们认为未定义为语言运行时/标准.

当复制构造函数或复制赋值运算符引发异常时,这两种实现似乎都会使容器具有未知内容(即,在异常之后不清楚容器占用哪些元素).

编辑1:请注意,这并不意味着我认为C++运行时存在不良行为,例如内存泄漏或未定义的值.但是,似乎或多或少未指明容器的内容是什么.特别是,容器的内容可能已完全(尽管一直)改变.

例如,考虑第三种(混合)方法:

  1. 创建n模板对象的副本列表val.
  2. 将此列表中的元素复制分配到目标容器中.

不同之处在于复制构造函数引发异常时对容器的影响.在这种情况下,如果复制构造函数抛出(但在复制赋值运算符抛出时仍会导致未指定的内容),则容器的内容保持不变.当使用指针(即不使用时std::vector)时,可能会遗漏复制分配,只重新排列指针,使操作原子化.例外.

至于noexcept容器元素:对象是通过创建的 …

c++ stl insert copy-constructor copy-assignment

3
推荐指数
1
解决办法
155
查看次数

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

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

propagate_on_container_copy_assignment  Alloc::propagate_on_container_copy_assignment if present, otherwise std::false_type
propagate_on_container_move_assignment  Alloc::propagate_on_container_move_assignment if present, otherwise std::false_type
propagate_on_container_swap             Alloc::propagate_on_container_swap if present, otherwise std::false_type
Run Code Online (Sandbox Code Playgroud)
is_always_equal(since C++17)            Alloc::is_always_equal if present, otherwise std::is_empty<Alloc>::type
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

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

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

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


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

templata<class Allocator>
struct my_container{
  Allocator alloc_;
  ...
  my_container& operator=(my_container const& other){ …
Run Code Online (Sandbox Code Playgroud)

allocator move-semantics copy-assignment c++11 move-assignment-operator

3
推荐指数
2
解决办法
1246
查看次数

free():在 C++ 中的 tcache 2 中检测到双空闲

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

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

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

即使我固定的一些代码的一部分,我的问题没有得到解决,当我发表评论或者除了Foo{1, "Hello World"};或者vec.push_back(std::move(Foo{}));,我不为什么得到它。

class Foo
{
public:
    Foo()
        : val{nullptr}, str{nullptr}
    {
        std::cout << "You are in empty constructor\n";
    }

    Foo(int the_val, const char *the_str)
        : val{new int}, str{new char[std::strlen(the_str + 1)]}
    {
        *val = the_val;
        std::cout << *val << '\n';
        std::strcpy(str, the_str);
        std::cout << str << '\n';
    }

    ~Foo()
    {
        if (val) {
            delete val;
        } else {
            std::cout << "val is empty\n"; …
Run Code Online (Sandbox Code Playgroud)

c++ move-constructor construct copy-assignment move-assignment-operator

3
推荐指数
2
解决办法
2万
查看次数

为什么在 C++ 中分配对象的地址不会改变?

在这个 C++ 示例中,一个类C有一个默认构造函数、一个复制构造函数和一个赋值运算符:

struct C {
    C();
    C(const C& c);
    C& operator=(const C& c);
};
Run Code Online (Sandbox Code Playgroud)

实现如下,带有一些用于跟踪对象的输出。我在注释中添加了一些示例地址作为对main下面程序的参考。

#include "C.h"
#include <iostream>
using namespace std;

C::C() {
    cout << "Standard constructor." << endl;
}

C::C(const C& c) {
    cout << "Copy constructor." << endl;
}

C& C::operator=(const C& c) {
    cout << "Address of reference argument: &c = " << &c << endl;      // F9B4
    cout << "Address of this: &*this =           " << &*this << endl;  // …
Run Code Online (Sandbox Code Playgroud)

c++ class memory-address assignment-operator copy-assignment

3
推荐指数
2
解决办法
155
查看次数