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 public:
// class is implemented using a dynamically allocated array (of templated type T). // default constructor
// We ensure that that m_size is always <= m_alloc and when a push_back or resize Vec(){
// call would violate this condition, the data is copied to a larger array. m_data = new T[2];
m_size = 0;
capacity = 2;
}
template <class T> class Vec { // 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;
}
}
public: // copy constructor
// TYPEDEFS Vec(const Vec& other){
typedef unsigned int size_type; 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];
}
}
// CONSTRUCTORS, ASSIGNMNENT OPERATOR, & DESTRUCTOR // destructor
Vec() { this->create(); } ~Vec(){
Vec(size_type n, const T& t = T()) { this->create(n, t); } delete [] m_data;
Vec(const Vec& v) { copy(v); } }
Vec& operator=(const Vec& v);
~Vec() { delete [] m_data; }
// MEMBER FUNCTIONS AND OTHER OPERATORS // assignment operator
T& operator[] (size_type i) { return m_data[i]; } Vec<T>& operator=(const Vec& other){
const T& operator[] (size_type i) const { return m_data[i]; } if(this != &other){
void push_back(const T& t); capacity = other.capacity;
void resize(size_type n, const T& fill_in_value = T()); m_size = other.m_size;
void clear() { delete [] m_data; create(); } m_data = new T[m_size];
bool empty() const { return m_size == 0; } for(unsigned int i=0;i<m_size;i++){
size_type size() const { return m_size; } m_data[i] = other.m_data[i];
}
}
return *this;
}
private: // [] operator
// PRIVATE MEMBER FUNCTIONS T& operator[](int i){
void create(); return m_data[i];
void create(size_type n, const T& val); }
void copy(const Vec<T>& v);
// REPRESENTATION unsigned int size(){
T* m_data; // Pointer to first location in the allocated array return m_size;
size_type m_size; // Number of elements stored in the vector }
size_type m_alloc; // Number of array locations allocated, m_size <= m_alloc
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;
}; };
// 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;
}
}
// Assign one vector to another, avoiding duplicate copying.
template <class T> Vec<T>& Vec<T>::operator=(const Vec<T>& v) {
if (this != &v) {
delete [] m_data;
this -> copy(v);
}
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
m_data[m_size] = val;
++ m_size;
}
// If n is less than or equal to the current size, just change the size. If n is
// 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.
template <class T> void Vec<T>::resize(size_type n, const T& fill_in_value) {
}
#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;
};