Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Templated Classes and Vector Implementation - Lecture Notes | CSCI 1200, Assignments of Data Structures and Algorithms

Material Type: Assignment; Class: DATA STRUCTURES; Subject: Computer Science; University: Rensselaer Polytechnic Institute; Term: Fall 2006;

Typology: Assignments

Pre 2010

Uploaded on 08/09/2009

koofers-user-lrp-1
koofers-user-lrp-1 🇺🇸

10 documents

1 / 6

Toggle sidebar

Related documents


Partial preview of the text

Download Templated Classes and Vector Implementation - Lecture Notes | CSCI 1200 and more Assignments Data Structures and Algorithms in PDF only on Docsity! CSCI-1200 Computer Science II — Fall 2006 Lecture 17 — Templated Classes & Vector Implementation Review from Lectures 15 & 16 • Arrays and pointers • Different types of memory (“automatic”, static, dynamic) • Dynamic allocation of arrays 17.1 Today’s Lecture • Designing our own container classes: – Mimic the interface of standard library containers – Study the design of memory management code and iterators. – Move toward eventually designing our own, more sophisticated classes. • Vector implementation • Templated classes • Copy constructors, assignment operators and destructors Reading: Koening & Moo Chapter 11 17.2 Vector Public Interface • In creating our own version of the STL vector class, we will start by considering the public interface: public: // MEMBER FUNCTIONS AND OTHER OPERATORS T& operator[] (size_type i); const T& operator[] (size_type i); void push_back(const T& t); iterator erase(iterator p); void resize(size_type n, const T& fill_in_value = T()); void clear(); bool empty() const; size_type size() const; // ITERATOR OPERATIONS iterator begin(); const_iterator begin(); iterator end(); const_iterator end(); • To implement our own generic (a.k.a. templated) vector class, we will implement all of these operations, manipulate the underlying representation, and discuss memory management. 17.3 Templated Class Declarations and Member Function Definitions • In terms of the layout of the code in vec.h (last 2 pages of the handout), the biggest difference is that this is a templated class. The keyword template and the template type name must appear before the class declaration: template <class T> class Vec • Within the class declaration, T is used as a type and all member functions are said to be “templated over type T”. In the actual text of the code files, templated member functions are often defined (written) inside the class declaration. • The templated functions defined outside the template class declaration must be preceeded by the phrase: template <class T> and then when Vec is referred to it must be as Vec<T> . For example, for member function create (two versions), we write: template <class T> void Vec<T>::create(... 17.4 Syntax and Compilation • Templated classes and templated member functions are not created/compiled/instantiated until they are needed. Compilation of the class declaration is triggered by a line of the form: Vec<int> v1; with int replacing T. This also compiles the default constructor for Vec<int> because it is used here. Other member functions are not compiled unless they are used. • When a different type is used with Vec, for example in the declaration: Vec<double> z; the template class declaration is compiled again, this time with double replacing T instead of int. Again, however, only the member functions used are compiled. • This is very different from ordinary classes, which are usually compiled separately and all functions are compiled regardless of whether or not they are needed. • The templated class declaration and the code for all used member functions must be provided where they are used. As a result, member functions definitions are often included within the class declaration or defined outside of the class delaration but still in the .h file. If member function definitions are placed in a separate .cpp file, this file must be #include-d, just like the .h file, because the compiler needs to see it in order to generate code. Note: Including function definitions in the .h for ordinary non-templated classes may lead to compilation errors about functions being “multiply defined”. Some of you have already seen these errors. 17.5 Member Variables Now, looking inside the Vec<T> class at the member variables: • m data is a pointer to the start of the array (after it has been allocated). Recall the close relationship between pointers and arrays. • m size indicates the number of locations currently in use in the vector. This is exactly what the size() member function should return, • m alloc is the total number of slots in the dynamically allocated block of memory. Drawing a picture, which we will do in class, will help clarify this, especially the distinction between m size and m alloc. 17.6 Typedefs, Iterators and Pointers • Several types are created through typedef statements in the first public area of Vec. Once created the names are used as ordinary class type names. For exmaple Vec<int>::iterator is an iterator type defined by the Vec<int> class. It is just a T *. Also, Vec<int>::size type is the size type, defined here as an unsigned int. • Thus, internal to the declarations and member functions, T* and iterator may be used interchangeably. • Also, the ++ and -- operators on pointers automatically apply to Vec iterators. 17.7 operator[] • Access to the individual locations of a Vec is provided through operator[]. Syntactically, use of this operator is translated by the compiler into a call to a function called operator[]. For example, if v is a Vec<int>, then: v[i] = 5; translates into: v.operator[](i) = 5; • In most classes there are two versions of operator[]: – A non-const version returns a reference to m data[i]. This is applied to non-const Vec objects. – A const version is the one called for const str objects. This also returns m data[i], but as a const reference, so it can not be modified. This version is the one used for const Vec objects. 2 17.18 Vec Declaration & Implementation (vec.h) #ifndef Vec_h_ #define Vec_h_ // 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: // TYPEDEFS typedef T* iterator; typedef const T* const_iterator; typedef unsigned int size_type; // CONSTRUCTORS, ASSIGNMNENT OPERATOR, & DESTRUCTOR Vec() { this->create(); } Vec(size_type n, const T& t = T()) { this->create(n, t); } Vec(const Vec& v) { copy(v); } Vec& operator=(const Vec& v); ~Vec() { delete [] m_data; } // 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); iterator erase(iterator p); 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; } // ITERATOR OPERATIONS iterator begin() { return m_data; } const_iterator begin() const { return m_data; } iterator end() { return m_data + m_size; } const_iterator end() const { return m_data + 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 (T* p = m_data; p != m_data + m_size; ++p) *p = val; } 5 // 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; } // Shift each entry of the array after the iterator. Return the iterator, // which will have the same value, but point to a different location. template <class T> typename Vec<T>::iterator Vec<T>::erase(iterator p) { } // 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 6
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved