[英]Copy Constructor and Destructor with a Dynamic Array
我一直在从事一个项目,在该项目中我应该使用动态数组来重新创建函数的基础。 该程序应具有默认的构造函数,该构造函数将创建一个大小为2的数组,并且“向量”的大小为0,直到将更多值添加到名为DynArray的向量类中。 当在阵列达到容量时尝试将.push_back插入向量时,我的程序应以2倍的容量对阵列进行新复制,并删除旧阵列。 到目前为止,这就是我要做的事情,而且我正在努力找出应该如何设置复制构造函数,以便使其正常工作。
我一直在努力使push_back和复制构造函数正常工作,而与此同时我碰到了任一个。
#include <iostream>
using namespace std;
class DynArray
{
public:
DynArray();
DynArray(const DynArry& origClass);
~DynArray();
int capacity();
int size();
void push_back(int newNum);
int at(int atNum);
private:
int arraySize;
int arrayCapacity;
int newNum;
int pushCounter;
int atNum;
int i;
int arrayVector [];
};
DynArray::DynArray() // default constructor, creates array with no elements and capacity 2
{
int* arrayVector = new int[2];
arrayCapacity = 2;
arraySize = 0;
pushCounter = 0; // used for push_back, increments through array every time a new number is added with push_back
return;
}
DynArray::DynArray(const DynArray& origClass) // copy constructor
{
cout << "Copy Constructor Called." << endl;
int* arrayVector = new int[2];
*arrayVector = *(origClass.arrayVector)
return;
}
void DynArray::push_back(int newNum)
{
if (arraySize == arrayCapacity) // if the capacity is the same as the current size, make a new array with twice the capacity, copy over values, delete the old array
{
arrayCapacity = arrayCapacity * 2;
int* newarrayVector = new int[arrayCapacity];
for (i = 0; i < arraySize; ++i)
{
*newarrayVector [i] = arrayVector[i];
}
arrayVector [pushCounter] = newNum; // push value to the next open value in the array
++arraySize; // increment so next push_back uses the following value
++pushCounter;
}
复制构造函数可以访问正在复制的对象的私有成员,因此它应该非常类似于您的resize方法。 有一些快捷方式(memcpy,std :: copy),但是最好学习如何使用循环。
因此,列出一些小问题:
几个明显的错误:
DynArray(const DynArry& origClass); ^
这可能是拼写错误。 没有DynArry
这样的类型。
int arrayVector [];
该成员声明格式错误。 不允许您使用未指定大小的成员数组。 由于您要重新实现动态数组,因此它可能应该是一个指针,用于保存动态分配的数组的地址。 指针声明如下:
int* arrayVector;
int* arrayVector = new int[2];
这会将动态数组的地址存储在本地自动变量中。 构造函数结束后,指针(即自动指针)将被破坏,并且数组将泄漏。 您可能应该改为this->arrayVector
进行更改。
*arrayVector = *(origClass.arrayVector)
这仅复制数组的第一个元素。 复制构造函数可能应该复制所有元素。 为此,您还应该构造一个动态数组,该数组与要复制的数组一样大。
此外,复制构造函数还保留许多未初始化的成员(例如arraySize
)。
*newarrayVector [i] = arrayVector[i];
此表达式格式错误。 您不能对整数使用间接操作。 您可能打算改为分配给数组元素:
newarrayVector [i] = arrayVector[i];
除此之外,您的重新分配遭受与构造函数相同的问题。 当函数结束时,新数组只是泄漏,因为您没有将其存储在成员中。
*arrayVector = *(origClass.arrayVector) return;
此表达式格式错误。 您可能忘记了分号。
您的副本构造函数应复制传递给它的对象的副本。
相反,它做到了;
DynArray::DynArray(const DynArray& origClass) // copy constructor { cout << "Copy Constructor Called." << endl; int* arrayVector = new int[2]; *arrayVector = *(origClass.arrayVector); // missing ; added here return; }
忽略输出到cout
,两个明显的问题是arrayVector
动态分配了两个元素,而不管origClass.arrayVector
有多少个元素。
语句int *arrayVector = *(origClass.arrayVector)
也根本不复制数组。
arrayVector
的指针(尽管具有相同的名称,该指针与DynArray
的成员无关)。 origClass.arrayVector
(单个int
)到的第一个元素 arrayVector
。 因此,它在功能上等效于arrayVector[0] = origClass.arrayVector[0]
。 这就是指针的工作方式。 arrayVector
不再存在,因为if对于构造函数的主体是局部的。 结果是动态分配的内存被泄漏(根本没有变量或DynArray
类的成员引用它,因此标准C ++中没有办法在后续代码中找到该内存)。 最后,你的拷贝构造函数没有任何其他成员复制origClass
( arraySize
, arrayCapacity
, newNum
, pushCounter
, atNum
, i
)给新的对象正在兴建。
相反,您(通常)需要做的是复制所有成员,而不仅仅是其中一个。 而且,如果要复制的成员之一是动态分配的数组(如您的情况),则构造函数需要首先构造一个新数组,然后将所有元素复制到该数组中,一次以某种形式循环。
例如,您可以
DynArray::DynArray(const DynArray& origClass) // copy constructor
{
arrayVector = new int[origClass.arrayCapacity];
这实际上改变了arrayVector
所述的构件DynaArray
(而不是声明一个局部变量)。 它还使该指针指向动态分配的数组,该数组的大小与origClass
大小相同。
这还没有完成,就是从origClass.arrayVector
复制数据。 *arrayVector = *(origClass.arrayVector)
我在上面提到的,使用*arrayVector = *(origClass.arrayVector)
无法完成此操作。 相反,构造函数需要这样做
for (int i = 0; i < origClass.arrayCapacity; ++i)
arrayVector[i] = origClass.arrayVector[i];
此步骤对于确保复制origClass.arrayVector
所有元素origClass.arrayVector
。 有多种方法可以做到这一点(例如,使用指针语法而不是数组语法),但是上面的内容就足够了。
然后有必要从origClass
复制所有其他成员。
arraySize = origClass.arraySize;
arrayCapacity = origClass.arrayCapacity;
newNum = origClass.newNum;
pushCounter = origClass.pushCounter;
atNum = origClass.atNum;
i = origClass.i;
} // the body of the constructor ends here.
DynArray
一句,让我感到DynArray
是,您为DynArray
分配了许多不需要的成员。 这些成员中的某些仅在特定成员函数(例如,循环计数器)中作为临时成员才需要。 这样做意味着DynArray
每个实例都有自己的那些变量副本。 那是不必要的-它们最好是局部变量,在需要它们的每个函数中声明。
现在,以上将(某种)工作,但是需要改进。 通常最好在构造函数中使用初始化程序,并让构造函数主体仅执行初始化程序中无法完成的工作。 这样做有很多优点,但是您可以做作业以弄清它们是什么。
因此,最后,我将复制构造函数实现为
DynArray::DynArray(const DynArray& origClass) : // initialiser list begins here
arrayVector(new int[origClass.arrayCapacity]),
arraySize(origClass.arraySize),
arrayCapacity(origClass.arrayCapacity),
newNum(origClass.newNum),
pushCounter(origClass.pushCounter),
atNum(origClass.atNum),
i(origClass.i)
{
// body of constructor starts here
for (int i = 0; i < origClass.arrayCapacity; ++i)
arrayVector[i] = origClass.arrayVector[i];
}
除了我之前没有提到过您没有该类的成员之外,此处的初始化程序列表仍会复制所有DynArray
成员。
请注意,复制数组元素的循环在构造函数的主体中,因为在初始化列表中无法轻松完成这种事情。
还要注意,变量i
(构造函数主体中的循环计数器)与名为i
的DynArray
成员没有关系。
最后, DynArray
的成员
int arrayVector [];
最好声明为指针。 它实际上不是数组。
int *arrayVector;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.