【问题标题】:Assignment operator is not called未调用赋值运算符
【发布时间】:2020-02-20 10:15:49
【问题描述】:
#include <iostream>

class MemoryBlock {
private:
    int length = 0;
    int* m_arr = nullptr;

public:
    // Constructor
    explicit MemoryBlock(int p_length) : length(p_length), m_arr(new int[length]) {
        std::cout << "In MemoryBlock(int), length is " << length << ".\n";
    }

    // Destructor
    ~MemoryBlock() {
        std::cout << "~MemoryBlock() is called. Deleting resources.\n";

        delete[] m_arr;
    }

    // Copy constructor
    MemoryBlock(const MemoryBlock& other) : length(other.length), m_arr(new int[other.length]) {
        std::cout << "In MemoryBlock(const MemoryBlock&), length is " << length << ".\n";

        for (int i = 0; i < length; ++i) {
            m_arr[i] = other.m_arr[i];
        }
    }

    // Move constructor
    MemoryBlock(MemoryBlock&& other) noexcept : length(0), m_arr(nullptr) {
        std::cout << "In MemoryBlock(MemoryBlock&&), length is " << other.length << ".\n";

        length = other.length;
        m_arr = other.m_arr;

        other.length = 0;
        other.m_arr = nullptr;
    }

    // Addition operator overloading
    MemoryBlock operator+(const MemoryBlock& other) {
        std::cout << "In operator+(const MemoryBlock&), adds length and array space. New length: " << length + other.length << '\n';

        int added_length = length + other.length;
        MemoryBlock sum(added_length);

        int idx = 0;
        int other_idx = 0;

        for (int i = 0; i < added_length; ++i) {
            if (i < length) {
                sum.m_arr[i] = m_arr[idx];
                ++idx;
            } else {
                sum.m_arr[i] = other.m_arr[other_idx];
                ++other_idx;
            }
        }

        return sum;
    }

    // Copy assignment operator
    MemoryBlock& operator=(const MemoryBlock& other) {
        std::cout << "In operator=(const MemoryBlock&), length is " << other.length << ".\n";

        if (this != &other) {
            delete[] m_arr;

            length = other.length;
            m_arr = new int[other.length];

            for (int i = 0; i < length; ++i) {
                m_arr[i] = other.m_arr[i];
            }
        }

        return *this;
    }

    // Move assignment operator
    MemoryBlock& operator=(MemoryBlock&& other) noexcept {
        std::cout << "In operator=(MemoryBlock&&), length is " << other.length << ".\n";

        if (this != &other) {
            delete[] m_arr;

            length = other.length;
            m_arr = other.m_arr;

            other.length = 0;
            other.m_arr = nullptr;
        }

        return *this;
    }
};

int main() {
    MemoryBlock mb1(11);
    MemoryBlock mb2(mb1);
    MemoryBlock mb3 = mb1 + mb2;

    std::cout << "----------------- End of main() -----------------\n";

    return 0;
}

Run code

我从Microsoft developer docs 获取了这个示例代码。我已生成对象 mb1 并将其复制到 mb2。然后将mb1 + mb2 分配给mb3。但正如您在结果中看到的那样,没有调用赋值运算符。

另外,似乎在调用加法运算符后生成了临时对象,但没有调用它的析构函数。调用的析构函数是mb1、mb2和mb3的一个。

为什么即使有句MemoryBlock mb3 = mb1 + mb2;,也不调用赋值运算符?为什么没有调用临时对象的析构函数?

结果:

In MemoryBlock(int), length is 11.
In MemoryBlock(const MemoryBlock&), length is 11.
In operator+(const MemoryBlock&), adds length and array space. New length: 22
In MemoryBlock(int), length is 22.  // Maybe temporary object?
----------------- End of main() -----------------
~MemoryBlock() is called. Deleting resources.
~MemoryBlock() is called. Deleting resources.
~MemoryBlock() is called. Deleting resources.

【问题讨论】:

  • MemoryBlock mb3 = mb1 + mb2; 调用复制构造函数。
  • 为什么?我该如何解决?
  • 因为它是对象的复制初始化。通过调整复制构造函数来修复它(无论如何)。
  • “赋值”是发生在已经存在的对象上的事情

标签: c++


【解决方案1】:

MemoryBlock mb3 = mb1 + mb2; 调用复制构造函数。

MemoryBlock mb3; mb3 = mb1 + mb2; 调用赋值运算符。

【讨论】:

  • 顺便说一句,如果您的赋值运算符采用MemoryBlock 而不是MemoryBlock&amp;,那么复制构造函数将在调用加号运算符之后和调用赋值运算符之前调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
  • 2019-10-06
  • 2011-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多