remove const square bracket operator

This commit is contained in:
Jidong Xiao
2024-02-02 13:07:31 -05:00
parent 9af84f9e76
commit 0dd3866d12
3 changed files with 76 additions and 194 deletions

View File

@@ -18,18 +18,18 @@ int main(){
teams.push_back("harvard"); teams.push_back("harvard");
// we can use a type alias defined inside a class even if there is no object of that class. The type alias becomes part of the class's scope and can be used anywhere in your code where the class's scope is visible. although no object of Vec is created in this code, the type alias size_type is still accessible because it is part of the class's scope. // we can use a type alias defined inside a class even if there is no object of that class. The type alias becomes part of the class's scope and can be used anywhere in your code where the class's scope is visible. although no object of Vec is created in this code, the type alias size_type is still accessible because it is part of the class's scope.
for(Vec<int>::size_type i = 0; i < teams.size(); i++){ for(unsigned int i = 0; i < teams.size(); i++){
std::cout << teams[i] << std::endl; std::cout << teams[i] << std::endl;
} }
std::cout<<"========="<<std::endl; std::cout<<"========="<<std::endl;
teams.pop_back(); teams.pop_back();
for(Vec<int>::size_type i = 0; i < teams.size(); i++){ for(unsigned int i = 0; i < teams.size(); i++){
std::cout << teams[i] << std::endl; std::cout << teams[i] << std::endl;
} }
std::cout<<"========="<<std::endl; std::cout<<"========="<<std::endl;
//teams.erase(2); //teams.erase(2);
for(Vec<int>::size_type i = 0; i < teams.size(); i++){ for(unsigned int i = 0; i < teams.size(); i++){
std::cout << teams[i] << std::endl; std::cout << teams[i] << std::endl;
} }
std::cout<<"========="<<std::endl; std::cout<<"========="<<std::endl;
@@ -46,8 +46,7 @@ int main(){
std::cout<<"========="<<std::endl; std::cout<<"========="<<std::endl;
// equivalent to Vector<double> w(v), w is a copy of the elements in v. // equivalent to Vector<double> w(v), w is a copy of the elements in v.
// we use the const keyword in front of a variable definition to indicate that the value of the variable cannot be changed after it is initialized. Vec<double> w = v;
const Vec<double> w = v;
for (unsigned int i = 0; i < v.size(); ++i){ for (unsigned int i = 0; i < v.size(); ++i){
std::cout << "w[" << i << "] is " << w[i] << " and v[" << i << "] is " << v[i] << std::endl; std::cout << "w[" << i << "] is " << w[i] << " and v[" << i << "] is " << v[i] << std::endl;
} }

View File

@@ -1,119 +1,79 @@
#ifndef Vec_h_ template<class T>
#define Vec_h_ class Vec{
// Simple implementation of the vector class, revised from Koenig and Moo. This
// class is implemented using a dynamically allocated array (of templated type T).
// We ensure that that m_size is always <= m_alloc and when a push_back or resize
// call would violate this condition, the data is copied to a larger array.
template <class T> class Vec {
public: public:
// TYPEDEFS // default constructor
typedef unsigned int size_type; Vec(){
m_data = new T[2];
m_size = 0;
capacity = 2;
}
// CONSTRUCTORS, ASSIGNMNENT OPERATOR, & DESTRUCTOR // other constructor
Vec() { this->create(); } Vec(int size, const T& val){
Vec(size_type n, const T& t = T()) { this->create(n, t); } m_data = new T[size];
Vec(const Vec& v) { copy(v); } m_size = size;
Vec& operator=(const Vec& v); capacity = size;
~Vec() { delete [] m_data; } for(int i=0;i<size;i++){
// MEMBER FUNCTIONS AND OTHER OPERATORS
T& operator[] (size_type i) { return m_data[i]; }
const T& operator[] (size_type i) const { return m_data[i]; }
void push_back(const T& t);
void resize(size_type n, const T& fill_in_value = T());
void clear() { delete [] m_data; create(); }
bool empty() const { return m_size == 0; }
size_type size() const { return m_size; }
private:
// PRIVATE MEMBER FUNCTIONS
void create();
void create(size_type n, const T& val);
void copy(const Vec<T>& v);
// REPRESENTATION
T* m_data; // Pointer to first location in the allocated array
size_type m_size; // Number of elements stored in the vector
size_type m_alloc; // Number of array locations allocated, m_size <= m_alloc
};
// Create an empty vector (null pointers everywhere).
template <class T> void Vec<T>::create() {
m_data = NULL;
m_size = m_alloc = 0; // No memory allocated yet
}
// Create a vector with size n, each location having the given value
template <class T> void Vec<T>::create(size_type n, const T& val) {
m_data = new T[n];
m_size = m_alloc = n;
for (size_type i = 0; i < m_size; i++) {
m_data[i] = val; m_data[i] = val;
} }
} }
// Assign one vector to another, avoiding duplicate copying. // copy constructor
template <class T> Vec<T>& Vec<T>::operator=(const Vec<T>& v) { Vec(const Vec& other){
if (this != &v) { capacity = other.capacity;
m_size = other.m_size;
m_data = new T[capacity];
for(unsigned int i=0;i<m_size;i++){
m_data[i] = other.m_data[i];
}
}
// destructor
~Vec(){
delete [] m_data; delete [] m_data;
this -> copy(v); }
// assignment operator
Vec<T>& operator=(const Vec& other){
if(this != &other){
capacity = other.capacity;
m_size = other.m_size;
m_data = new T[m_size];
for(unsigned int i=0;i<m_size;i++){
m_data[i] = other.m_data[i];
}
} }
return *this; return *this;
}
// Create the vector as a copy of the given vector.
template <class T> void Vec<T>::copy(const Vec<T>& v) {
}
// Add an element to the end, resize if necesssary.
template <class T> void Vec<T>::push_back(const T& val) {
if (m_size == m_alloc) {
// Allocate a larger array, and copy the old values
} }
// Add the value at the last location and increment the bound
// [] operator
T& operator[](int i){
return m_data[i];
}
unsigned int size(){
return m_size;
}
void push_back(const T& val){
if(m_size >= capacity){
capacity = capacity * 2;
// allocate memory for the new array and move content of m_data to the new array.
T* temp = new T[capacity];
for(unsigned int i=0;i<m_size;i++){
temp[i] = m_data[i];
}
delete [] m_data;
m_data = temp;
}
m_data[m_size] = val; m_data[m_size] = val;
++ m_size; m_size++;
} }
void pop_back(){
// If n is less than or equal to the current size, just change the size. If n is m_size--;
// greater than the current size, the new slots must be filled in with the given value. }
// Re-allocation should occur only if necessary. push_back should not be used. private:
template <class T> void Vec<T>::resize(size_type n, const T& fill_in_value) { int capacity;
int m_size;
T* m_data;
};
}
#endif

View File

@@ -1,77 +0,0 @@
template<class T>
class Vec{
public:
typedef unsigned int size_type;
// default constructor
Vec(){
m_data = new T[2];
m_size = 0;
capacity = 2;
}
// other constructor
Vec(int size, const T& val){
m_data = new T[size];
m_size = size;
capacity = size;
for(int i=0;i<size;i++){
m_data[i] = val;
}
}
// copy constructor
Vec(const Vec& other){
capacity = other.capacity;
m_size = other.m_size;
m_data = new T[capacity];
for(unsigned int i=0;i<m_size;i++){
m_data[i] = other.m_data[i];
}
}
// destructor
~Vec(){
delete [] m_data;
}
// assignment operator
Vec<T>& operator=(const Vec& other){
if(this != &other){
capacity = other.capacity;
m_size = other.m_size;
m_data = new T[m_size];
for(unsigned int i=0;i<m_size;i++){
m_data[i] = other.m_data[i];
}
}
return *this;
}
// [] operator
T& operator[](int i){
return m_data[i];
}
// the const version of [] operator
const T& operator[](int i) const {
return m_data[i];
}
unsigned int size(){
return m_size;
}
void push_back(const T& val){
if(m_size >= capacity){
capacity = capacity * 2;
// allocate memory for the new array and move content of m_data to the new array.
T* temp = new T[capacity];
for(unsigned int i=0;i<m_size;i++){
temp[i] = m_data[i];
}
delete [] m_data;
m_data = temp;
}
m_data[m_size] = val;
m_size++;
}
void pop_back(){
m_size--;
}
private:
int capacity;
int m_size;
T* m_data;
};