使用运算符重载时如何 return 结果 +

How do I return results while using operator overloading +

当我使用运算符重载并返回它调用我的复制构造函数的临时对象时,我有一些代码让我感到困惑,但当我返回我的 class 成员时 temp.size 它调用我的参数化构造函数 MyClass(int size) 并且一切正常。我感兴趣的是它是如何工作的以及它与什么有关。下面的代码。

class MyClass
{
private:
    int* data;
    int size;
    
public:
    MyClass()
    {
        size = 0;
    }
    MyClass(int size)
    {
        this->size = size;
        data = new int[size];
        for (size_t i = 0; i < size; i++)
        {
            data[i] = rand();
        }
    }
    MyClass(const MyClass& obj)
    {
        this->size = obj.size;
        this->data = new int[size];
        for (size_t i = 0; i < size; i++)
        {
            data[i] = obj.data[i];
        }
    }
    MyClass operator+(const MyClass& obj)
    {
        MyClass temp;
        temp.size = this->size + obj.size;
        return temp.size;
    }
    friend ostream& operator<<(ostream& os, MyClass& obj);

    ~MyClass()
    {
        delete[]data;
    }
};

ostream& operator<<(ostream & os, MyClass & obj)
{
    os << obj.size;
    return os;
}

int main()
{
    MyClass a(5);
    MyClass b(a);
    MyClass c = a + b;
    cout << c;
    return 0;
}

如果可以使用std::vector,你的代码可以变成:

class MyClass {
private:
    vector<int> data;
public:
    MyClass(int size) {
        data.resize(size);
        for (size_t i = 0; i < size; i++) {
            data[i] = rand();
        }
    }
    MyClass operator+(const MyClass& obj) {
        return data.size() + obj.data.size();
    }
    friend ostream& operator<<(ostream& os, MyClass& obj);
};

ostream& operator<<(ostream& os, MyClass& obj) {
    os << obj.data.size();
    return os;
}

否则不要delete未初始化的指针。 (所以要么调用 new 要么设置为 nullptr)。 您没有在默认构造函数中初始化指针,因此不要在析构函数中调用 delete。 更改默认构造函数以将 data 设置为 nullptr

    MyClass() {
        data = nullptr;
        size = 0;
    }

另外,当你还没有初始化指针时,不要从数组中复制。当您设置 size 变量时,您并没有创建数组。您应该创建一个名为 setSize 的函数并将您的代码更改为:

    MyClass(int size) {
        data = nullptr;
        setSize(size);
    }
    void setSize(int size) {
        this->size = size;
        delete[] data;
        data = new int[size];
        for (size_t i = 0; i < size; i++) {
            data[i] = rand();
        }
    }
    MyClass operator+(const MyClass& obj) {
        MyClass temp;
        temp.setSize(this->size + obj.size);
        return temp.size;
    }

每当您需要更改大小时,您应该使用 setSize 函数来确保数组也已创建。

我发现您的代码有几个问题:

  • 您的默认构造函数未初始化 data

  • 您的 operator+ 未尝试将值从 this->dataobj.data 复制到 temp.data,因此 temp.data 未初始化。

  • 您的 operator+ 返回了错误的 MyClass 对象。它麻烦地准备一个名为 tempMyClass 对象,然后在退出时完全丢弃 temp。通过将 temp.size 传递给 return,您将通过 MyClass(int size) 构造函数创建 另一个 MyClass 对象,它会生成所有新的随机数据。您需要 return 您准备的 temp 对象。然后编译器要么调用你的复制构造函数将temp赋值给main()中的c,要么optimize away the copyoperator+直接操作[=30] =].

  • 根据 Rule of 3. Nothing in your example actually invokes a copy assignment, but you need to implement the operator properly nonetheless. And if you are using C++11 or later, you should also follow the Rule of 5 as well, by adding a move constructor and a move assignment operator. However, if you can change your design to use std::vector instead of new[], then you can follow the Rule of 0,您缺少一个复制赋值运算符,让编译器为您完成所有艰苦的工作。

话虽如此,请尝试更像这样的事情:

#include <iostream>
#include <algorithm>
#include <utility> // C++11 and later only...
#include <cstdlib>
#include <ctime>    

class MyClass
{
private:
    int* data;
    size_t size;
    
public:
    MyClass(size_t size = 0) : data(NULL), size(size)
    {
        if (size > 0)
        {
            data = new int[size];
            // in C++11 and later, consider using std::uniform_int_distribution instead of rand()!
            std::generate(data, data + size, std::rand);
        }
    }

    MyClass(const MyClass& obj) : data(NULL), size(obj.size)
    {
        if (size > 0)
        {
            data = new int[size];
            std::copy(obj.data, obj.data + obj.size, data);
        }
    }

    // C++11 and later only...
    MyClass(MyClass&& obj) : data(NULL), size(0)
    {
        std::swap(size, obj.size);
        std::swap(data, obj.data);
    }

    ~MyClass()
    {
        delete[] data;
    }

    MyClass& operator=(const MyClass& rhs)
    {
        if (&rhs != this)
        {
            MyClass temp(rhs);
            std::swap(size, temp.size);
            std::swap(data, temp.data);
        }
        return *this;
    }
    
    MyClass& operator=(MyClass&& rhs)
    {
        MyClass temp(std::move(rhs));
        std::swap(size, temp.size);
        std::swap(data, temp.data);
        return *this;
    }

    MyClass operator+(const MyClass& obj) const
    {
        MyClass temp;
        temp.size = size + obj.size;
        if (temp.size > 0)
        {
            temp.data = new int[temp.size];
            std::copy(data, data + size, temp.data);
            std::copy(obj.data, obj.data + obj.size, temp.data + size);
        }
        return temp;
    }

    friend std::ostream& operator<<(std::ostream& os, const MyClass& obj);
};

std::ostream& operator<<(std::ostream& os, const MyClass& obj)
{
    os << obj.size;
    for(size_t i = 0; i < obj.size; ++i)
    {
        os << " " << obj.data[i];
    }
    return os;
}

int main()
{
    std::srand(std::time(0));
    MyClass a(5);
    MyClass b(a);
    MyClass c = a + b;
    std::cout << c;
    return 0;
}

可以简化为:

#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>

class MyClass
{
private:
    std::vector<int> data;
    
public:
    MyClass(size_t size = 0) : data(size)
    {
        std::generate(data.begin(), data.end(), std::rand);
    }

    MyClass operator+(const MyClass& obj) const
    {
        MyClass temp;
        if (!data.empty() || !obj.data.empty())
        {
            temp.data.reserve(data.size() + obj.data.size());
            temp.data.insert(temp.data.end(), data.begin(), data.end());
            temp.data.insert(temp.data.end(), obj.data.begin(), obj.data.end());
        }
        return temp;
    }

    friend std::ostream& operator<<(std::ostream& os, const MyClass& obj);
};

std::ostream& operator<<(std::ostream& os, const MyClass& obj)
{
    os << obj.size;
    for(size_t i = 0; i < obj.size; ++i)
    {
        os << " " << obj.data[i];
    }
    return os;
}

int main()
{
    std::srand(std::time(0));
    MyClass a(5);
    MyClass b(a);
    MyClass c = a + b;
    std::cout << c;
    return 0;
}