由于种种原因,我被迫提供复制构造和运营商=为我的课。我想我不需要 operator= 如果我定义的一个副本构造函数,但是 QList 想要一个。把它放到一边,我讨厌代码重复,这样有错吗这样做?

Fixture::Fixture(const Fixture& f) {
    *this = f;
}

Fixture& Fixture::operator=(const Fixture& f) {
    m_shape         = f.m_shape;
    m_friction      = f.m_friction;
    m_restitution   = f.m_restitution;
    m_density       = f.m_density;
    m_isSensor      = f.m_isSensor;
    return *this;
}

只是出于好奇,有没有办法打开它这样大量的代码,在复制和构造函数 operator= 以某种方式利用它吗?我试过了 return Fixture(f); 但是它不喜欢那样


看来我需要使它更清楚,复制构造和分配运营商已经默示禁止通过类我是继承。为什么?因为这是一个抽象的基类不应该是实例在它自己的。这一类,但是, 意味着独立。

有帮助吗?

解决方案

这是不好的,因为operator=不能依靠一个建立对象了。你应该这样做的其他方式,并可以使用复制交换成语。

在这里你就必须在所有元素复制的情况下,可以使用隐式生成的赋值运算符。

在其他情况下,你将不得不做一些此外,多释放和复制内存。这就是副本交换成语是良好的。它不仅是优雅的,但它也提供了这样的分配不会抛出异常,如果它只是交换原语。让我们一类指向你需要复制一个缓冲区:

Fixture::Fixture():m_data(), m_size() { }

Fixture::Fixture(const Fixture& f) {
    m_data = new item[f.size()];
    m_size = f.size();
    std::copy(f.data(), f.data() + f.size(), m_data);
}

Fixture::~Fixture() { delete[] m_data; }

// note: the parameter is already the copy we would
// need to create anyway. 
Fixture& Fixture::operator=(Fixture f) {
    this->swap(f);
    return *this;
}

// efficient swap - exchanging pointers. 
void Fixture::swap(Fixture &f) {
    using std::swap;
    swap(m_data, f.m_data);
    swap(m_size, f.m_size);
}

// keep this in Fixture's namespace. Code doing swap(a, b)
// on two Fixtures will end up calling it. 
void swap(Fixture &a, Fixture &b) {
  a.swap(b);
}

这就是我平时写的赋值运算符。阅读要速度?通过绕不寻常的赋值运算符签名值传递(按值传递)。

其他提示

复制构造函数和分配是完全不同 - 分配通常需要释放资源,它的替换对象,副本构造函数正在一个尚未初始化的对象上。因为在这里,你显然没有特殊要求(没有“释放”需要在分配),你的做法是好的。更一般地,你可能有辅助方法(在析构函数,并在指定的开始称作)“的对象是持有释放所有资源”还有“这些东西复制到对象”的一部分,这相当接近典型的拷贝构造函数的工作(或大部分,反正; - )。

你简单地做在你的例子成员明智的副本和任务。这是不是你需要自己写一些东西。编译器可以生成隐复制和赋值操作是这样做。你只需要当编译器生成的那些不适合写自己的拷贝构造函数,赋值和/或析构函数(即如果你通过指针或类似的东西管理一些资源)

我想你遇到的问题,如果您的运营商=真的成为虚拟的。

我会建议写,做,然后拷贝有拷贝构造和操作的功能(也许静态)=调用该函数。

是的,这是良好做法和应(几乎)总是能做到的。此外抛在一析构和默认的构造(甚至如果你把它私人).

在詹姆斯Coplien1991年书 先进C++, 这是描述为的一部分"正统的规范的形式"。在书中,他提倡一种默认的构造、复制构造、转让操作员和一析构函数。

在一般情况下,您 必须 使用正统的规范形式,如果:

  • 你想要支持,分配的对象的类,或者希望通过这些对象,如按价值的参数的一个函数,
  • 对象包含针对对象的基准计算,或类析构执行 delete 在一个数据对象的成员。

你的 应该 使用正统的规范形式针对任何平凡的课程序,为统一跨类和管理日益复杂的各类过程的程序的演进。

Coplien提供的网页的原因,这种模式和我做不到他们的正义在这里。然而,一个关键项目已经涉及的是能够清除的对象是被复盖。

我想你应该使用initializer list初始化对象的成员变量。如果您的变量是primitive-types的,那么也没关系。否则,分配是从初始化不同。


您可以通过初始化copy constructor0内的指针与一个小窍门做,那么你可以调用在assignment operator安全地删除:

Fixture::Fixture(const Fixture& f) : myptr(0) {
    *this = f;
}
Fixture& Fixture::operator=(const Fixture& f) {
    // if you have a dynamic array for example, delete other wise.
    delete[] myptr;
    myptr = new int[10];
    // initialize your array from the other object here.
    ......
    return *this;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top