rem*_*emi 1 c++ pointers overloading
如我错了请纠正我:
我知道当有一个成员是指针的类时,类对象的副本将导致表示相同内存地址的指针.这可能导致对一个类对象进行更改以影响此对象的所有副本.
对此的解决方案可以是重载=运算符.鉴于下面的示例,尝试创建动态数组类,为什么对MyArray1进行更改会更改MyArray2:
数组类:
#include <iostream>
#include <cstdlib>
class Array
{
public:
Array(int N){ //constructor sets size of array
size = N;
arr = new int[N];
}
~Array();
int size; //array elements
int *arr; //dynamic array pointer
//fill array with random values between 1 and 100
void fillArray() {
for (size_t i = 0; i < size; i++)
{arr[i] = std::rand()%100;}
}
//print out array to console
void printArray() {
for (size_t i = 0; i < size; i++)
{ std::cout << arr[i] << " ";}
std::cout << std::endl;
}
//overload = operator
Array &operator=(Array arr2) {
std::swap(size, arr2.size);
std::swap(arr, arr2.arr);
return *this;
}
};
Run Code Online (Sandbox Code Playgroud)
Main.cpp的:
#include "Array.h"
#include <iostream>
int main(){
Array MyArray1(8), MyArray2(8);
MyArray1.fillArray();
MyArray2 = MyArray1;
std::cout << "Print out arrays:" << std::endl;
std::cout << "MyArray1: "; MyArray1.printArray();
std::cout << "MyArray2: "; MyArray2.printArray();
std::cout << std::endl;
MyArray1.arr[5] = 1000;
std::cout << "MyArray2: "; MyArray2.printArray();
MyArray1.fillArray();
std::cout << "MyArray2: "; MyArray2.printArray();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
示例输出:
Print out arrays:
MyArray1: 41 67 34 0 69 24 78 58
MyArray2: 41 67 34 0 69 24 78 58
MyArray2: 41 67 34 0 69 1000 78 58
MyArray2: 62 64 5 45 81 27 61 91
Run Code Online (Sandbox Code Playgroud)
如上所示,对MyArray1所做的更改会更改MyArray2.我假设=的重载是错误的,但我怎么写得正确呢?
解:
感谢Chris Dodd的评论,我意识到这只是在我的课程中实现这样的复制构造函数:
Array(const Array &arr2){
size = arr2.size;
arr = new int[size];
for (size_t i = 0; i < size; i++)
{
arr[i] = arr2.arr[i];
}
}
Run Code Online (Sandbox Code Playgroud)
您的代码存在多个问题.最重要的是,正如对问题的评论所指出的,除了编写自己的赋值运算符之外,还需要编写复制构造函数(并实现析构函数).
第二件事是,你的赋值运算符通过值而不是引用来获取参数,这会导致默认的复制构造函数MyArray1在传递给赋值运算符之前创建一个副本.这是问题的直接来源所在.
另一件事是您的赋值运算符的行为类似于移动赋值而不是复制赋值,这意味着它将原始项的值替换为其当前(默认)值.
最后,您真的想要实现析构函数,以便它删除您的数组而不是泄漏它.
总结一下,你想要这样的东西(编辑:灵感来自蒂莫西答案的复制作业检查):
class Array
{
public:
Array(int N)
{
size = N;
arr = new int[N];
}
//destructor
~Array()
{
delete[] arr;
}
//copy constructor
Array(const Array& arr2)
{
size = arr2.size;
arr = new int[size];
std::memcpy(arr, arr2.arr, size);
}
//overload = operator
Array& operator=(const Array& arr2)
{
if (this == &arr2)
return *this; //self assignment
if (arr != NULL)
delete[] arr; //clean up already allocated memory
size = arr2.size;
arr = new int[size];
std::memcpy(arr, arr2.arr, size);
return *this;
}
private:
int size; //array elements
int *arr; //dynamic array pointer
};
Run Code Online (Sandbox Code Playgroud)