这个重载的运算符做什么?

时间:2019-04-15 21:02:36

标签: c++ arrays pointers

我不确定函数中以下重载运算符的作用。

1 个答案:

答案 0 :(得分:1)

复制构造函数的介绍

假设我有一个SomeClass的实例:

SomeClass someVar;

如果我想创建SomeClass的副本,可以将其分配给新变量:

SomeClass newCopy = someVar;

这通过调用newCopy的副本构造函数来构造SomeClass,而newCopy现在是someVar的副本。它们引用不同的对象,它们具有不同的地址,并且如果我更改一个成员变量,则不会影响另一个。

我也可以这样写:

SomeClass newCopy = SomeClass(someVar); 

使用new创建指针:

如果我要创建指向SomeClass的指针,可以执行以下操作:

// Allocates memory, and default-constructs an instance of SomeClass on the heap
SomeClass* ptr = new SomeClass();

但是,我不仅限于该构造函数。我可以使用SomeClass的任何构造函数,包括复制构造函数:

// Allocates memory, and copy-constructs an instance of SomeClass on the heap
SomeClass* ptrToCopy = new SomeClass(someVar); 

使用指针执行此操作

现在,假设我想创建someHeapCopy的副本:

SomeClass copyOfCopy = *ptrToCopy; 

这将取消引用指针,然后调用SomeClass的副本构造函数以创建其副本。我可以显式地调用复制构造函数:

SomeClass copyOfCopy = SomeClass(*ptrToCopy); 

或者,我可以使用new对副本进行堆分配:

SomeClass* ptrToCopyOfCopy = new SomeClass(*ptrToCopy); 

解释您的代码

让我们创建一个包含该代码的简单类

class MyValue {
   public:
    int value;
}; 

class MyList {
    std::vector<MyValue*> values;
    void clearValues() {
        for(MyValue* ptr : values) {
            delete ptr; 
        }
        values.clear();
    }
   public:
    MyList& operator=(MyList const& other) {
        // Return if this class is the same as the other one
        if(this == &other) return *this; 
        // delete the old values
        clearValues();
        // resize values
        values.resize(other.values.size()); 
        for(size_t i = 0; i < values.size(); i++) {
            values[i] = new MyValue(*other.values[i]); 
        }
    }
    ~MyList() {
        clearValues(); 
    }
};

此部分:

for(size_t i = 0; i < values.size(); i++) {
    values[i] = new MyValue(*other.values[i]); 
}

与写作相同:

for(size_t i = 0; i < values.size(); i++) {
    // Get a pointer to the other value
    const MyValue* ptrToOtherValue = other.values[i]; 
    // Get a reference from that pointer
    const MyValue& refToOtherValue = *ptrToOtherValue;
    // Allocate a new value that's a copy of the old one
    MyValue* copyOfValue = new MyValue(refToOtherValue); 
    // Assign the pointer to the array
    values[i] = copyOfValue;
}

简化此代码以避免内存泄漏

我们可以使用unique_ptr来编写MyList的简单得多的版本:

class MyValue {
   public:
    int value;
}; 

class MyList {
    std::vector<std::unique_ptr<MyValue>> values;
   public:
    MyList& operator=(MyList const& other) {
        // Return if this class is the same as the other one
        if(this == &other) return *this; 

        // resize the array
        values.resize(other.size());

        // Reassign the values
        for(size_t i = 0; i < values.size(); i++) {
            values[i].reset(new MyValue(*values[i])); 
        }
    }
};

这段代码要简单得多,并且保证不会有任何内存泄漏。

  • 我不必具有clearValues功能
  • 如果我真的想清除这些值,可以致电values.clear()
  • 在重新分配值之前,我不必清除这些值,因为reset会自动为我删除旧值
  • 我不必为MyList编写析构函数,因为std::unique_ptr会自动删除自身