复制构造函数和赋值运算符

复制构造函数和赋值运算符

本文介绍了这是好的代码吗? (复制构造函数和赋值运算符)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于某种原因,我不得不为我的类提供一个复制构造函数和一个operator =。我想我不需要 operator = 如果我定义了一个复制ctor,但 QList 想要一个。把这放在一边,我讨厌代码重复,所以这样做有什么不对吗?

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

夹具& 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;
}

出于好奇,没有办法切换它,的代码是在复制ctor和 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; }

//注意:参数已经是副本,我们将
//需要创建。
夹具Fixture :: operator =(Fixture f){
this-> swap(f);
return * this;
}

//有效交换 - 交换指针。
void Fixture :: swap(Fixture& f){
using std :: swap;
swap(m_data,f.m_data);
swap(m_size,f.m_size);
}

//保存在Fixture的命名空间中。代码做交换(a,b)
//在两个Fixtures将最终调用它。
void swap(Fixture& a,Fixture& b){
a.swap(b);
}

这是我通常写赋值运算符的方式。阅读关于异常的赋值运算符签名(传递值)。


For one reason or another, I'm forced to provide both a copy constructor and an operator= for my class. I thought I didn't need operator= if I defined a copy ctor, but QList wants one. Putting that aside, I hate code duplication, so is there anything wrong with doing it this way?

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;
}

And just out of curiosity, there's no way to switch it so that the bulk of the code is in the copy ctor and operator= somehow utilizes it? I tried return Fixture(f); but it didn't like that.


It appears I need to make it more clear that the copy constructor and assignment operator have been implicitly disabled by the class I am inheriting from. Why? Because it's an abstract base class that shouldn't be instantiated on its own. This class, however, is meant to stand alone.

解决方案

This is bad, because the operator= can't rely on a set-up object anymore. You should do it the other way around, and can use the copy-swap idiom.

In the case where you just have to copy over all elements, you can use the implicitly generated assignment operator.

In other cases, you will have to do something in addition, mostly freeing and copying memory. This is where the copy-swap idiom is good for. Not only is it elegant, but it also provide so an assignment doesn't throw exceptions if it only swaps primitives. Let's a class pointing to a buffer that you need to copy:

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);
}

That's how i write the assignment operator usually. Read Want speed? Pass by value about the unusual assignment operator signature (pass by value).

这篇关于这是好的代码吗? (复制构造函数和赋值运算符)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 15:07