[英]Copy Constructor and Destructor with a Dynamic Array
I've been working on a project in which I am supposed to recreate the basics of the function using a dynamic array. 我一直在从事一个项目,在该项目中我应该使用动态数组来重新创建函数的基础。 The program should have a default constructor, which creates an array with a size of 2, and the "vector"'s size is 0 until more values are added to the vector class, named DynArray.
该程序应具有默认的构造函数,该构造函数将创建一个大小为2的数组,并且“向量”的大小为0,直到将更多值添加到名为DynArray的向量类中。 When there's an attempt to .push_back into the vector when the array is at capacity, my program should make a new coppy of the array with 2x the capacity, and delete the old array.
当在阵列达到容量时尝试将.push_back插入向量时,我的程序应以2倍的容量对阵列进行新复制,并删除旧阵列。 This is what I have so far, and I'm struggling to figure out how the copy constructor should be set up so it works appropriately.
到目前为止,这就是我要做的事情,而且我正在努力找出应该如何设置复制构造函数,以便使其正常工作。
I've been jumping between working on getting push_back and the copy constructor working properly when I've run into a wall with either in the mean time. 我一直在努力使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;
}
Your copy constructor can access private members of the object it is copying, so it should be very much like your resize method. 复制构造函数可以访问正在复制的对象的私有成员,因此它应该非常类似于您的resize方法。 There are shortcuts (memcpy, std::copy) but you are better off learning how to use the loop.
有一些快捷方式(memcpy,std :: copy),但是最好学习如何使用循环。
So, list of little issues you have: 因此,列出一些小问题:
Few obvious bugs: 几个明显的错误:
DynArray(const DynArry& origClass); ^
This is probably a typo. 这可能是拼写错误。 There is no such type as
DynArry
. 没有
DynArry
这样的类型。
int arrayVector [];
This member declaration is ill formed. 该成员声明格式错误。 You are not allowed to have member arrays of unspecified size.
不允许您使用未指定大小的成员数组。 Since you're re-implementing a dynamic array, this should probably instead be a pointer to hold the address of the dynamically allocated array.
由于您要重新实现动态数组,因此它可能应该是一个指针,用于保存动态分配的数组的地址。 A pointer is declared like this:
指针声明如下:
int* arrayVector;
int* arrayVector = new int[2];
This stores the address of the dynamic array in a local automatic variable. 这会将动态数组的地址存储在本地自动变量中。 As soon as the constructor ends, the pointer - being automatic - is destroyed and the array is leaked.
构造函数结束后,指针(即自动指针)将被破坏,并且数组将泄漏。 You should probably make the changes to
this->arrayVector
instead. 您可能应该改为
this->arrayVector
进行更改。
*arrayVector = *(origClass.arrayVector)
This copies only the first element of the array. 这仅复制数组的第一个元素。 The copy constructor should probably copy all of the elements.
复制构造函数可能应该复制所有元素。 To that end, you should also construct a dynamic array that is as big as the one you're copying from.
为此,您还应该构造一个动态数组,该数组与要复制的数组一样大。
Also, the copy constructor leaves many of the members uninitialized (such as arraySize
). 此外,复制构造函数还保留许多未初始化的成员(例如
arraySize
)。
*newarrayVector [i] = arrayVector[i];
This expression is ill-formed. 此表达式格式错误。 You cannot use the indirection operation on an integer.
您不能对整数使用间接操作。 You probably intended to assign to the array element instead:
您可能打算改为分配给数组元素:
newarrayVector [i] = arrayVector[i];
Besides that, your reallocation suffers from the same problem as your constructors. 除此之外,您的重新分配遭受与构造函数相同的问题。 The new array is simply leaked when the function ends since you don't store it in a member.
当函数结束时,新数组只是泄漏,因为您没有将其存储在成员中。
*arrayVector = *(origClass.arrayVector) return;
This expression is ill-formed. 此表达式格式错误。 You may have forgotten a semicolon.
您可能忘记了分号。
Your copy constructor should make a copy the object passed to it. 您的副本构造函数应复制传递给它的对象的副本。
Instead it does this; 相反,它做到了;
DynArray::DynArray(const DynArray& origClass) // copy constructor { cout << "Copy Constructor Called." << endl; int* arrayVector = new int[2]; *arrayVector = *(origClass.arrayVector); // missing ; added here return; }
Ignoring output to cout
, the two obvious problems are that arrayVector
is dynamically allocated with two elements, regardless of how many elements there are in origClass.arrayVector
. 忽略输出到
cout
,两个明显的问题是arrayVector
动态分配了两个元素,而不管origClass.arrayVector
有多少个元素。
The statement int *arrayVector = *(origClass.arrayVector)
also does not copy an array at all. 语句
int *arrayVector = *(origClass.arrayVector)
也根本不复制数组。
arrayVector
(which is unrelated to the member of DynArray
, despite having the same name). arrayVector
的指针(尽管具有相同的名称,该指针与DynArray
的成员无关)。 origClass.arrayVector
(a single int
) to the first element of arrayVector
. origClass.arrayVector
(单个int
)到的第一个元素 arrayVector
。 So it is functionally equivalent to arrayVector[0] = origClass.arrayVector[0]
. arrayVector[0] = origClass.arrayVector[0]
。 That's the way pointers work. arrayVector
declared ceases to exist, because if is local to the body of the constructor. arrayVector
不再存在,因为if对于构造函数的主体是局部的。 A consequence is that the dynamically allocated memory is leaked (no variables, or members of your DynArray
class, refer to it at all, so there is no way in standard C++ to find that memory in subsequent code). DynArray
类的成员引用它,因此标准C ++中没有办法在后续代码中找到该内存)。 Lastly, your copy constructor does not copy any other members of origClass
( arraySize
, arrayCapacity
, newNum
, pushCounter
, atNum
, i
) to the new object being constructed. 最后,你的拷贝构造函数没有任何其他成员复制
origClass
( arraySize
, arrayCapacity
, newNum
, pushCounter
, atNum
, i
)给新的对象正在兴建。
Instead, what you (typically) need to do is copy ALL of of the members, not just one of them. 相反,您(通常)需要做的是复制所有成员,而不仅仅是其中一个。 And, if one of the members being copied is a dynamically allocated array - as in your case - the constructor needs to first construct a new array, and THEN copy all elements to it - one at a time, in a loop of some form.
而且,如果要复制的成员之一是动态分配的数组(如您的情况),则构造函数需要首先构造一个新数组,然后将所有元素复制到该数组中,一次以某种形式循环。
For example, you could do 例如,您可以
DynArray::DynArray(const DynArray& origClass) // copy constructor
{
arrayVector = new int[origClass.arrayCapacity];
This actually modifies the arrayVector
member of the DynaArray
(rather than declaring a local variable). 这实际上改变了
arrayVector
所述的构件DynaArray
(而不是声明一个局部变量)。 It also makes that pointer point at a dynamically allocated array of the same size as in origClass
. 它还使该指针指向动态分配的数组,该数组的大小与
origClass
大小相同。
What this hasn't done is copy data from origClass.arrayVector
. 这还没有完成,就是从
origClass.arrayVector
复制数据。 AS I noted above, this cannot be done using *arrayVector = *(origClass.arrayVector)
. *arrayVector = *(origClass.arrayVector)
我在上面提到的,使用*arrayVector = *(origClass.arrayVector)
无法完成此操作。 Instead the constructor needs to do this 相反,构造函数需要这样做
for (int i = 0; i < origClass.arrayCapacity; ++i)
arrayVector[i] = origClass.arrayVector[i];
This step is essential to ensure ALL the elements of origClass.arrayVector
are copied. 此步骤对于确保复制
origClass.arrayVector
所有元素origClass.arrayVector
。 There are variations of HOW this is done (eg using pointer syntax rather than array syntax) but the above will suffice. 有多种方法可以做到这一点(例如,使用指针语法而不是数组语法),但是上面的内容就足够了。
Then it is necessary to copy all of the other members from origClass
. 然后有必要从
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.
As an aside, it strikes me you have given your DynArray
a number of members it doesn't need. DynArray
一句,让我感到DynArray
是,您为DynArray
分配了许多不需要的成员。 Some of those members are only needed as temporaries in particular member functions (eg loop counters). 这些成员中的某些仅在特定成员函数(例如,循环计数器)中作为临时成员才需要。 Doing that means EVERY instance of
DynArray
has its own copy of those variables. 这样做意味着
DynArray
每个实例都有自己的那些变量副本。 That is unnecessary - they would be better off being local variables, declared in each function where they are needed. 那是不必要的-它们最好是局部变量,在需要它们的每个函数中声明。
Now, the above will (sort of) work, but needs to be improved. 现在,以上将(某种)工作,但是需要改进。 It is generally better to use initialisers in constructors where possible, and have the constructor body only do things that can't be done in initialisers.
通常最好在构造函数中使用初始化程序,并让构造函数主体仅执行初始化程序中无法完成的工作。 There are various advantages to doing this, but you can do homework to find out what they are.
这样做有很多优点,但是您可以做作业以弄清它们是什么。
In the end, therefore, I would implement the copy constructor as 因此,最后,我将复制构造函数实现为
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];
}
Not withstanding my previous aside that you have unnecessary members of the class, the initialiser list here still copies ALL of your DynArray
members. 除了我之前没有提到过您没有该类的成员之外,此处的初始化程序列表仍会复制所有
DynArray
成员。
Note that the loop to copy array elements is in the body of the constructor, since that sort of thing cannot be done readily in an initialiser list. 请注意,复制数组元素的循环在构造函数的主体中,因为在初始化列表中无法轻松完成这种事情。
Also note that the variable i
(the loop counter in the constructor body) has no relationship to member of DynArray
named i
. 还要注意,变量
i
(构造函数主体中的循环计数器)与名为i
的DynArray
成员没有关系。
Lastly, the member of DynArray
最后,
DynArray
的成员
int arrayVector [];
would be better declared as a pointer. 最好声明为指针。 It is not actually an array.
它实际上不是数组。
int *arrayVector;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.