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

新星

当我使用运算符重载并返回临时对象时,我的代码使我感到困惑,它调用了我的复制构造函数,并且遇到异常,但是当我返回类成员temp.size时,它调用了我的参数化构造函数MyClass(int大小),一切正常。我对它的工作原理以及与之相关的东西很感兴趣。下面的代码。

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;
}
雷米·勒博

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

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

  • operator+是不是尝试从复制值this->dataobj.datatemp.data,因而留下temp.data未初始化。

  • operator+返回错误的MyClass对象。麻烦的是准备一个MyClass名为对象temp,然后temp在退出时将其完全丢弃通过传递temp.sizereturn,您将通过构造函数创建另一个 MyClass对象MyClass(int size),该对象将生成所有新的随机数据。您需要改为准备returntemp对象。然后,编译器将调用您的副本构造函数以将其分配tempcin main(),或者它将优化掉副本operator+直接对其进行操作c

  • 根据3规则,您缺少副本分配运算符您的示例中没有任何内容真正调用拷贝分配,但是您仍然需要正确实现操作符。而且,如果您使用的是C ++ 11或更高版本,则还应该遵循规则5,通过添加move构造函数和move赋值运算符。但是,如果您可以更改设计以使用std::vector而不是new[],则可以遵循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;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章