使用运算符重载时如何 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->data
和 obj.data
复制到 temp.data
,因此 temp.data
未初始化。
您的 operator+
返回了错误的 MyClass
对象。它麻烦地准备一个名为 temp
的 MyClass
对象,然后在退出时完全丢弃 temp
。通过将 temp.size
传递给 return
,您将通过 MyClass(int size)
构造函数创建 另一个 MyClass
对象,它会生成所有新的随机数据。您需要 return
您准备的 temp
对象。然后编译器要么调用你的复制构造函数将temp
赋值给main()
中的c
,要么optimize away the copy让operator+
直接操作[=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;
}
当我使用运算符重载并返回它调用我的复制构造函数的临时对象时,我有一些代码让我感到困惑,但当我返回我的 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->data
和obj.data
复制到temp.data
,因此temp.data
未初始化。您的
operator+
返回了错误的MyClass
对象。它麻烦地准备一个名为temp
的MyClass
对象,然后在退出时完全丢弃temp
。通过将temp.size
传递给return
,您将通过MyClass(int size)
构造函数创建 另一个MyClass
对象,它会生成所有新的随机数据。您需要return
您准备的temp
对象。然后编译器要么调用你的复制构造函数将temp
赋值给main()
中的c
,要么optimize away the copy让operator+
直接操作[=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 ofnew[]
, 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;
}