[英]Why this template class doesn't work properly?
#include <bits/stdc++.h>
using namespace std;
template<class T>
class Array{
public:
Array(int sizeOfArray=1){
arr = new T[sizeOfArray];
for(int i=0;i<sizeOfArray;i++){
arr[i] = 0;
}
maxSize = sizeOfArray;
currentElement = 0;
}
T* growArray(){
T* newarr = new T[maxSize*2];
for(int i=0;i<maxSize;i++){
newarr[i] = arr[i];
}
maxSize = maxSize*2;
return newarr;
}
void add(T element){
if(currentElement>=maxSize){
arr = growArray();
}
arr[currentElement] = element;
currentElement++;
}
T get(int index){
return arr[index];
}
int nrElements(){
return currentElement;
}
int length(){
return maxSize;
}
~Array(){
delete arr;
}
protected:
private:
T* arr;
int maxSize;
int currentElement;
};
template<class T>
Array<T> add(Array<T> &arr1, Array<T> &arr2){
int newsize = arr1.nrElements()+arr2.nrElements()+5;
int aux;
Array<T> arr3(newsize);
for(int i=0;i<arr1.nrElements();i++){
aux = arr1.get(i);
arr3.add(aux);
}
for(int i=0;i<arr2.nrElements();i++){
aux = arr2.get(i);
arr3.add(aux);
}
return arr3;
}
int main()
{
Array<int> arr(2);
for(int i=0;i<1000;i++){
arr.add(i);
}
Array<int> arr2(2);
for(int i=1000;i<2000;i++){
arr2.add(i);
}
Array<int> arr3;
arr3 = add(arr, arr2);
for(int i=0;i<arr3.nrElements();i++){
cout<<arr3.get(i)<<" ";
}
return 0;
}
该功能正常工作。 我的意思是在“ aux = arr1.get(i);”这一行上 正在执行其工作,但是当我尝试读取main()中arr3的元素时,前两个元素不是0和1。程序显示了其他大数字,例如175243462和152614213。
OP报告的错误很可能是违反三规则的结果。 什么是三法则?
template<class T>
Array<T> add(Array<T> &arr1, Array<T> &arr2)
{
int newsize = arr1.nrElements() + arr2.nrElements() + 5;
int aux;
Array<T> arr3(newsize); <<- made a local array
for (int i = 0; i < arr1.nrElements(); i++)
{
aux = arr1.get(i);
arr3.add(aux);
}
for (int i = 0; i < arr2.nrElements(); i++)
{
aux = arr2.get(i);
arr3.add(aux);
}
return arr3; <<- return by value. May trigger a copy of arr3, then destroy arr3
}
没有复制构造函数或赋值运算符,因此编译器生成的默认方法非常简单。 他们盲目地调用其成员变量的复制和赋值运算符,并且指针的默认复制行为是复制内存位置而不是指向的内存。 这意味着副本和源的arr
成员都指向同一存储位置。 Array
析构函数delete arr;
,因此副本现在指向已释放的内存。 现在,访问任何副本都是未定义的行为,销毁任何副本将导致重复删除。 非常糟糕的一幕。
解决方案,无论如何要解决此错误,请实现复制构造函数和赋值运算符。 这方面有一些帮助: 运算符重载
奖励错误:
void add(T element)
{
if (currentElement >= maxSize)
{
arr = growArray(); <<- did not release the old array pointed at by arr
}
arr[currentElement] = element;
currentElement++;
}
add
泄漏内存,因为它不会delete
arr
更换前arr
这是比较难做到add
(不是很多不可否认),比它在growArray
如此,
void growArray() <<- returns nothing
{
T* newarr = new T[maxSize * 2];
for (int i = 0; i < maxSize; i++)
{
newarr[i] = arr[i];
}
maxSize = maxSize * 2;
delete arr; <<- clean up old arr
arr = newarr; <<- assign arr here
}
和
void add(T element)
{
if (currentElement >= maxSize)
{
growArray(); <<- everything done by growArray
}
arr[currentElement] = element;
currentElement++;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.