我的任务是为SimpleVector创建push_back和pop_back函数,这些函数基本上必须按照您的想象完成。我试图以这种方式向现有阵列添加元素,但它不起作用。它添加0而不是我在main中传入的数字。关于为什么的任何想法?
SimpleVector.h
// SimpleVector class template
#ifndef SIMPLEVECTOR_H
#define SIMPLEVECTOR_H
#include <iostream>
#include <new> // Needed for bad_alloc exception
#include <cstdlib> // Needed for the exit function
using namespace std;
template<class T>
class SimpleVector
{
private:
T *aptr; // To point to the allocated array
int arraySize; // Number of elements in the array
void memError(); // Handles memory allocation errors
void subError(); // Handles subscripts out of range
public:
// Default constructor
SimpleVector()
{
aptr = 0;
arraySize = 0;
}
// Constructor declaration
SimpleVector(int);
// Copy constructor declaration
SimpleVector(const SimpleVector &);
// Destructor declaration
~SimpleVector();
// Accessor to return the array size
int size() const
{
return arraySize;
}
// Accessor to return a specific element
T getElementAt(int position);
// Overloaded [] operator declaration
T &operator[](const int &);
void push_back(SimpleVector, int);
void pop_back(SimpleVector, int);
};
//***********************************************************
// Constructor for SimpleVector class. Sets the size of the *
// array and allocates memory for it. *
//***********************************************************
template<class T>
SimpleVector<T>::SimpleVector(int s)
{
arraySize = s;
// Allocate memory for the array.
try
{
aptr = new T[s];
}
catch (bad_alloc)
{
memError();
}
// Initialize the array.
for (int count = 0; count < arraySize; count++)
*(aptr + count) = 0;
}
//*******************************************
// Copy Constructor for SimpleVector class. *
//*******************************************
template<class T>
SimpleVector<T>::SimpleVector(const SimpleVector &obj)
{
// Copy the array size.
arraySize = obj.arraySize;
// Allocate memory for the array.
aptr = new T[arraySize];
if (aptr == 0)
memError();
// Copy the elements of obj's array.
for (int count = 0; count < arraySize; count++)
*(aptr + count) = *(obj.aptr + count);
}
//**************************************
// Destructor for SimpleVector class. *
//**************************************
template<class T>
SimpleVector<T>::~SimpleVector()
{
if (arraySize > 0)
delete[] aptr;
}
//*******************************************************
// memError function. Displays an error message and *
// terminates the program when memory allocation fails. *
//*******************************************************
template<class T>
void SimpleVector<T>::memError()
{
cout << "ERROR:Cannot allocate memory.\n";
exit(EXIT_FAILURE);
}
//***********************************************************
// subError function. Displays an error message and *
// terminates the program when a subscript is out of range. *
//***********************************************************
template<class T>
void SimpleVector<T>::subError()
{
cout << "ERROR: Subscript out of range.\n";
exit(EXIT_FAILURE);
}
//*******************************************************
// getElementAt function. The argument is a subscript. *
// This function returns the value stored at the sub- *
// script in the array. *
//*******************************************************
template<class T>
T SimpleVector<T>::getElementAt(int sub)
{
if (sub < 0 || sub >= arraySize)
subError();
return aptr[sub];
}
//*******************************************************
// Overloaded [] operator. The argument is a subscript. *
// This function returns a reference to the element *
// in the array indexed by the subscript. *
//*******************************************************
template<class T>
T &SimpleVector<T>::operator[](const int &sub)
{
if (sub < 0 || sub >= arraySize)
subError();
return aptr[sub];
}
#endif
template<class T>
void SimpleVector<T>::push_back(SimpleVector obj, int newval)
{
arraySize = obj.arraySize + 1;
// Allocate memory for the array.
aptr = new T[arraySize];
if (aptr == 0)
memError();
// Copy the elements of obj's array.
for (int count = 0; count < (arraySize - 1); count++)
*(aptr + count) = *(obj.aptr + count);
obj.aptr[(arraySize)] = newval;
}
的main.cpp
// This program demonstrates the SimpleVector template.
#include <iostream>
#include "SimpleVector.h"
using namespace std;
int main()
{
const int SIZE = 10; // Number of elements
int amtToPrnt = 10;
int count; // Loop counter
// Create a SimpleVector of ints.
SimpleVector<int> intTable(SIZE);
// Store values in the two SimpleVectors.
for (count = 0; count < SIZE; count++)
{
intTable[count] = (count * 2);
}
// Display the values in the SimpleVectors.
cout << "These values are in intTable:\n";
for (count = 0; count < amtToPrnt; count++)
cout << intTable[count] << " ";
cout << endl;
intTable.push_back(intTable, 20);
cout << "These values are in intTable after adding one more value:\n";
for (count = 0; count < ++amtToPrnt; count++)
cout << intTable[count] << " ";
cout << endl;
/*
intTable.push_back(intTable, 22);
cout << "These values are in intTable after adding one more value:\n";
for (count = 0; count < ++amtToPrnt; count++)
cout << intTable[count] << " ";
cout << endl;
intTable.push_back(intTable, 24);
cout << "These values are in intTable after adding one more value:\n";
for (count = 0; count < ++amtToPrnt; count++)
cout << intTable[count] << " ";
cout << endl;
*/
return 0;
}
答案 0 :(得分:2)
SimpleVector.h
void push_back(int);
我删除了SimpleVector
以减少内存使用量。
template <class T>
void SimpleVector<T>::push_back(int newval){
// Allocate memory for the array in the temporary array.
T * tmpArray = new T [arraySize + 1];
// Copy the elements of old array.
for(int count = 0; count < arraySize; count++)
*(tmpArray + count) = *(aptr + count);
// Push new value
*(tmpArray + arraySize) = newval;
// Delete old array
delete[] aptr;
// Copy array
aptr = tmpArray;
// Increase size
arraySize++;
}
的main.cpp
intTable.push_back(20);
amtToPrnt++;
cout << "These values are in intTable after adding one more value:\n";
for (count = 0; count < amtToPrnt; count++)
cout << intTable[count] << " ";
cout << endl;
结果:
旁注:
你应该重构你的SimpleVector
。如果您不需要,请不要使用pass by value。我建议公众arraySize
公开了解vector
中有多少数据。
答案 1 :(得分:1)
SimpleVector<T>::push_back
有点像残骸。我们来看看,好吗?
void SimpleVector<T>::push_back(SimpleVector obj, int newval)
SimpleVector obj
按值传递,因此操作的obj
是副本。建议通过引用传递。但为什么这首先出现呢? push_back推回SimpleVector
和新值有什么用?建议重新考虑这种方法。
{
arraySize = obj.arraySize + 1;
// Allocate memory for the array.
aptr = new T[arraySize];
行。这一切都很好。除了,如果aptr
已经指向内存怎么办?你必须首先delete[]
,但那么你会复制什么?建议在此处使用临时变量,并在复制和删除完成后分配临时变量。
if (aptr == 0)
memError();
这绝不会发生。 new
会对分配错误抛出bad_alloc
,因此如果new
失败,程序将永远不会到达此处。早些时候,该计划就是这样做的:
try
{
aptr = new T[s];
}
catch (bad_alloc)
{
memError();
}
你很可能想再次这样做。
使用0代替nullptr
也是不好的形式。 0是幻数而且它不是指针。
// Copy the elements of obj's array.
for (int count = 0; count < (arraySize - 1); count++)
*(aptr + count) = *(obj.aptr + count);
所有时髦。除了aptr[count]
已经足够的笨重的指针算术之外,没有什么可以看到的。但是,如上所述,这是push_back
函数的意外行为。
obj.aptr[(arraySize)] = newval;
obj
仍然是obj.arraySize
大小,arraySize
是一个更大。接下来,数组被索引为0 .. obj.arraySize-1
,因此这不会写入一个,而是在数组末尾写入两个元素并调用未定义的行为。谁知道这样做会有什么结果?我当然不会。
接下来,它修改了obj
,这是一个即将被销毁的副本。我怀疑*(aptr + arraySize - 1) = newval;
会更有用。
}
当我写这篇文章时,一个完全可以服务的应该做什么回答。请参阅。
优化:为什么不为自己节省大量的调整大小和复制,并将大小增加一倍,而不是总是增加1倍?
答案 2 :(得分:0)
当你调用push_back时,第一个参数按值传递。换句话说,创建临时副本。然后你分配一个新的数组(不删除原来的 - 内存泄漏!)并将this
中的ptr更改为新数组。很好,但是然后你将新值放入临时向量中,该向量在从函数返回后被销毁。