我一直致力于一个项目,我应该使用动态数组重新创建函数的基础知识。程序应该有一个默认的构造函数,它创建一个大小为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;
}
答案 0 :(得分:0)
您的复制构造函数可以访问它正在复制的对象的私有成员,因此它应该与您的resize方法非常相似。有快捷方式(memcpy,std :: copy)但你最好学习如何使用循环。
所以,你有一些小问题:
答案 1 :(得分:0)
几个明显的错误:
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;
这个表达形式错误。你可能忘记了分号。
答案 2 :(得分:0)
您的复制构造函数应该复制传递给它的对象。
相反,它会这样做;
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
的第一个元素(a
单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
的{{1}}成员(而不是声明一个局部变量)。它还使该指针指向动态分配的数组,其大小与DynaArray
中相同。
这还没有完成从origClass
复制数据。如上所述,使用origClass.arrayVector
无法做到这一点。相反,构造函数需要执行此操作
*arrayVector = *(origClass.arrayVector)
此步骤对于确保复制 for (int i = 0; i < origClass.arrayCapacity; ++i)
arrayVector[i] = origClass.arrayVector[i];
的所有元素至关重要。这有多少变化(例如使用指针语法而不是数组语法),但上面就足够了。
然后有必要从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(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
的{{1}}成员没有关系。
最后,DynArray
i
会更好地声明为指针。它实际上不是一个数组。
DynArray