I having trouble implementing the pop_back(); callling it from main(). I understand it's use with something that is less complex but so far its just killing me using it as the SimpleVector public member. The error reads I don't have the right class to the left of .pop_back();intTable.PopBack();
template <class T>
class SimpleVector
{
private:
T *aptr;
int arraySize;
void subError(); // Handles subscripts out of range
public:
SimpleVector(int); // Constructor
SimpleVector(const SimpleVector &); // Copy constructor
~SimpleVector(); // Destructor
int size()
{ return arraySize; }
T &operator[](int); // Overloaded [] operator
void print(); // outputs the array elements.
void PopBack(); //removes an element
//void PushBack(T const &);
};
//*******************************************************
// 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;
aptr = new T [s];
for (int count = 0; count < arraySize; count++)
aptr[count] = T();
}
//******************************************************
// Copy Constructor for SimpleVector class. *
//******************************************************
template <class T>
SimpleVector<T>::SimpleVector(const SimpleVector &obj)
{
arraySize = obj.arraySize;
aptr = new T [arraySize];
for(int count = 0; count < arraySize; count++)
aptr[count] = obj[count];
}
//*****************************************************
// Destructor for SimpleVector class. *
//*****************************************************
template <class T>
SimpleVector<T>::~SimpleVector()
{
if (arraySize > 0)
delete [] aptr;
}
//******************************************************
// 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(0);
}
//*******************************************************
// 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[](int sub)
{
if (sub < 0 || sub >= arraySize)
subError();
return aptr[sub];
}
//********************************************************
// prints all the entries is the array. *
//********************************************************
template <class T>
void SimpleVector<T>::print( )
{
for (int k = 0; k < arraySize; k++ )
cout << aptr[k] << " ";
cout << endl;
}
//*******************************************************
// removes an elemnt from array *
//*******************************************************
template <class T>
void SimpleVector<T>::PopBack()
{
aptr.pop_back();
}
aptr is a pointer dude and that too of a typr T. So if suppose type T is an int then your pointer will be int *aptr. And int does not have a function call pop_back()
And even if somehow, miraculously, int (from above example) runs properly on pop_back. Then another error would be calling aptr.pop_back();. Because aptr is a pointer, valid call will be aptr->pop_back();
It will, as I explained in my above post. Post your main function's code then I think it would be more clear.
What is the type of T in your code. Like for ex. in your main, are you declaring something like
1 2 3 4 5 6
int main() {
SimpleVector<int> obj;
obj.pop_back();
return 0;
}
If yes, then in this case T of template <class T> is an int hence your aptr is int *aptr; and, as I said, int does not have pop_back() function.
#include <iostream>
#include <vector>
#include "SimpleVector.h"
usingnamespace std;
int main()
{
constint SIZE = 10;
SimpleVector<int> intTable(SIZE);
SimpleVector<double> doubleTable(SIZE);
// Store values in the arrays.
for (int x = 0; x < SIZE; x++)
{
intTable[x] = (x * 2);
doubleTable[x] = (x * 2.14);
}
// Display the values in the arrays.
cout << "\nThese values are in intTable:\n";
// intTable.PopBack(); // use of pop_back
intTable.PopBack();
intTable.print();
cout << "\nThese values are in doubleTable:\n";
doubleTable.print();
// Use the built-in + operator on array elements.
for (int x = 0; x < SIZE; x++)
{
intTable[x] = intTable[x] + 5;
doubleTable[x] = doubleTable[x] + 1.5;
}
// Display the values in the array.
cout << "\nThese values are in intTable:\n";
intTable.print();
cout << "\nThese values are in doubleTable:\n";
doubleTable.print();
// Use the built-in ++ operator on array elements.
for (int x = 0; x < SIZE; x++)
{
intTable[x]++;
doubleTable[x]++;
}
// Display the values in the array.
cout << "\nThese values are in intTable:\n";
intTable.print();
cout << "\nThese values are in the doubleTable:\n";
doubleTable.print();
cout << endl;
return 0;
}
Ok, let me try once again, what I am trying to say is: T *aptr; and then using aptr->pop_back(); is not valid.
If you would have had something like vector<T> aobj; and then if you would have done aobj.pop_back(); OR vector<T> *aptr; and then aptr->pop_back(); then these two are valid.
Because vector<T> aobj; and vector<T> *aptr; ARE VECTOR TYPES. So we can use it's provided functions like pop_back();. However, if you write T *aptr; and then you write SimpleVector<int> obj; then since your SimpleVector class is a template class, that means where ever you have written T, it would be replaced by the data type you have specified in SimpleVector<int> obj; in this case this is an int
Try this simple code
1 2 3 4 5 6 7
int main() {
int i = 10;
int *aptr = &i;
aptr->pop_back(); //invalid
return 0;
}
Do you think above code is valid? NO, it is not valid because int is not a class, hence there is no such member function defined named as pop_back();. On the other hand vector is a Container Class. Therefore, it has a member function named pop_back(); defined in it's definition. Therefore, you can use pop_back(); only on the vector type of objects and pointers.
If you want your class to work with primative types like int and double, you will need to write your own pop method from scratch. You could just decrease arraySize by one. You don't have to, but it might be convenient if the pop method returns the last element from before the pop.
Push is going to be more complex because the array memory may need to be reallocated.
It sounds like the fact that I'm using a pointer creates some issues. My teacher had another example of something similar ,but it didn't use a pointer and worked primo. This case is what it is and it asked the user to modify by adding more member function. I think I just might scratch the pointer.