adding the iterator implementation code
This commit is contained in:
committed by
JamesFlare1212
parent
5d67ac91fc
commit
716d955a73
145
lectures/10_linked_lists/vec.h
Normal file
145
lectures/10_linked_lists/vec.h
Normal file
@@ -0,0 +1,145 @@
|
||||
template <class T>
|
||||
class vec {
|
||||
public:
|
||||
// default constructor
|
||||
vec(){
|
||||
m_size = 0;
|
||||
m_capacity = 2;
|
||||
m_data = new T[m_capacity];
|
||||
// std::cout << "calling default constructor" << std::endl;
|
||||
}
|
||||
|
||||
// other constructor
|
||||
vec(int number, const T& value){
|
||||
m_size = number;
|
||||
m_capacity = m_size * 2;
|
||||
m_data = new T[m_capacity];
|
||||
for(int i=0; i<m_size; ++i){
|
||||
m_data[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
vec(const vec& other){
|
||||
m_size = other.m_size;
|
||||
m_capacity = other.m_capacity;
|
||||
m_data = new T[m_capacity];
|
||||
for(int i=0; i<m_size; ++i){
|
||||
m_data[i] = other.m_data[i];
|
||||
}
|
||||
}
|
||||
|
||||
// assignment operator
|
||||
// a = b = c; a = (b = c);
|
||||
// a = b;
|
||||
vec& operator=(const vec& other){
|
||||
// use this if statement here so as to avoid self-assignment.
|
||||
if(this != &other){
|
||||
m_size = other.m_size;
|
||||
m_capacity = other.m_capacity;
|
||||
m_data = new T[m_capacity];
|
||||
for(int i=0; i<m_size; ++i){
|
||||
m_data[i] = other.m_data[i];
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// destructor
|
||||
~vec(){
|
||||
// std::cout << "calling destructor" << std::endl;
|
||||
delete [] m_data;
|
||||
}
|
||||
|
||||
int size();
|
||||
/*int size(){
|
||||
return m_size;
|
||||
}*/
|
||||
|
||||
T& operator[](int index){
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
void push_back(const T& element){
|
||||
// if we have space
|
||||
if(m_size < m_capacity){
|
||||
m_data[m_size] = element;
|
||||
}else{
|
||||
// if we don't have space
|
||||
m_capacity = m_capacity* 2;
|
||||
T* new_data = new T[m_capacity];
|
||||
// copy the existing elements to new location
|
||||
for(int i=0; i<m_size; ++i){
|
||||
new_data[i] = m_data[i];
|
||||
}
|
||||
new_data[m_size] = element;
|
||||
delete [] m_data;
|
||||
m_data = new_data;
|
||||
}
|
||||
m_size++;
|
||||
}
|
||||
|
||||
void pop_back(){
|
||||
m_size--;
|
||||
}
|
||||
// nested class
|
||||
class iterator {
|
||||
private:
|
||||
T* ptr;
|
||||
public:
|
||||
// constructor
|
||||
iterator(T* p){
|
||||
ptr = p;
|
||||
}
|
||||
// dereference operator
|
||||
T& operator*(){
|
||||
return *ptr;
|
||||
}
|
||||
T* operator->(){
|
||||
return ptr;
|
||||
}
|
||||
// pre-increment
|
||||
iterator& operator++(){
|
||||
++ptr;
|
||||
return *this;
|
||||
}
|
||||
// post-increment
|
||||
// special syntax here, we must write the int keyword here in the post-increment function.
|
||||
iterator operator++(int){
|
||||
iterator temp = *this;
|
||||
++ptr;
|
||||
return temp;
|
||||
}
|
||||
bool operator!=(const iterator& other){
|
||||
return (ptr != other.ptr);
|
||||
}
|
||||
};
|
||||
iterator begin();
|
||||
//iterator begin(){
|
||||
// we want to have an iterator pointing to the beginning of the vec container.
|
||||
// return iterator(m_data);
|
||||
//}
|
||||
iterator end(){
|
||||
// we want to have an iterator pointing to the end.
|
||||
return iterator(m_data + m_size);
|
||||
}
|
||||
private:
|
||||
T* m_data;
|
||||
int m_capacity; // whole capacity
|
||||
int m_size; // current size
|
||||
};
|
||||
|
||||
// below we demonstrate that member functions can also be written outside of the templated class definition:
|
||||
|
||||
// why we need typename here: The compiler does not automatically assume that vec<T>::iterator is a type.
|
||||
// Instead, it first assumes that anything after :: is a member variable or function, not a type.
|
||||
// To explicitly tell the compiler that vec<T>::iterator is a type, we must use the typename keyword:
|
||||
template <class T>
|
||||
typename vec<T>::iterator vec<T>::begin(){
|
||||
return vec<T>::iterator(m_data);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int vec<T>::size(){
|
||||
return m_size;
|
||||
}
|
||||
33
lectures/10_linked_lists/vec_main.cpp
Normal file
33
lectures/10_linked_lists/vec_main.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <iostream>
|
||||
//#include <vector>
|
||||
#include "vec.h"
|
||||
|
||||
int main(){
|
||||
vec<std::string> teams;
|
||||
teams.push_back("rpi");
|
||||
teams.push_back("wpi");
|
||||
teams.push_back("yale");
|
||||
teams.push_back("brown");
|
||||
teams.push_back("cornell");
|
||||
teams.push_back("colgate");
|
||||
teams.push_back("miami");
|
||||
teams.push_back("colorado");
|
||||
teams.push_back("harvard");
|
||||
std::cout << "==== teams ==== " << std::endl;
|
||||
int size = teams.size();
|
||||
for(int i=0; i<size; ++i){
|
||||
std::cout << teams[i] << std::endl;
|
||||
}
|
||||
|
||||
// this line calls the other constructor.
|
||||
vec<double> v(4, 0.0);
|
||||
v[0] = 13.1; v[2] = 3.14;
|
||||
|
||||
vec<double>::iterator itr = v.begin();
|
||||
std::cout << "the first element of v is: " << *itr << std::endl;
|
||||
std::cout << "printing elements in v: " << std::endl;
|
||||
while(itr != v.end()){
|
||||
std::cout << "print " << *itr << std::endl;
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user