C++ Tutorial/Data Types/Your array
creates a safe array class.
<source lang="cpp">#include <iostream>
- include <new>
- include <cstdlib>
using namespace std;
class array {
int *p; int size;
public:
array(int sz) { try { p = new int[sz]; } catch (bad_alloc xa) { cout << "Allocation Failure\n"; exit(EXIT_FAILURE); } size = sz; } ~array() { delete [] p; } // copy constructor array(const array &a); void put(int i, int j) { if(i>=0 && i<size) p[i] = j; } int get(int i) { return p[i]; }
};
// Copy Constructor array::array(const array &a) {
int i; try { p = new int[a.size]; } catch (bad_alloc xa) { cout << "Allocation Failure\n"; exit(EXIT_FAILURE); } for(i=0; i<a.size; i++) p[i] = a.p[i];
}
int main() {
array num(10); int i; for(i=0; i<10; i++) num.put(i, i); for(i=9; i>=0; i--) cout << num.get(i); cout << "\n"; // create another array and initialize with num array x(num); // invokes copy constructor for(i=0; i<10; i++) cout << x.get(i); return 0;
}</source>
Define your own array class
<source lang="cpp">#include <iostream> using std::cerr; using std::cout; using std::cin; using std::endl; using std::ostream; using std::istream;
- include <iomanip>
using std::setw;
- include <cstdlib>
using std::exit; class Array {
friend ostream &operator<<( ostream &, const Array & ); friend istream &operator>>( istream &, Array & );
public:
Array( int = 10 ); Array( const Array & ); ~Array(); int getSize() const; const Array &operator=( const Array & ); bool operator==( const Array & ) const; bool operator!=( const Array &right ) const { return ! ( *this == right ); } int &operator[]( int ); int operator[]( int ) const;
private:
int size; int *ptr;
}; Array::Array( int arraySize ) {
size = arraySize; ptr = new int[ size ]; for ( int i = 0; i < size; i++ ) ptr[ i ] = 0;
} Array::Array( const Array &arrayToCopy ) : size( arrayToCopy.size ) {
ptr = new int[ size ]; for ( int i = 0; i < size; i++ ) ptr[ i ] = arrayToCopy.ptr[ i ];
} Array::~Array() {
delete [] ptr;
} int Array::getSize() const {
return size;
} const Array &Array::operator=( const Array &right ) {
delete [] ptr; size = right.size; ptr = new int[ size ]; for ( int i = 0; i < size; i++ ) ptr[ i ] = right.ptr[ i ]; return *this;
} bool Array::operator==( const Array &right ) const {
if ( size != right.size ) return false; for ( int i = 0; i < size; i++ ) if ( ptr[ i ] != right.ptr[ i ] ) return false; return true;
} int &Array::operator[]( int subscript ) {
return ptr[ subscript ];
} int Array::operator[]( int subscript ) const {
return ptr[ subscript ];
} istream &operator>>( istream &input, Array &a ) {
for ( int i = 0; i < a.size; i++ ) input >> a.ptr[ i ]; return input;
} ostream &operator<<( ostream &output, const Array &a ) {
int i; for ( i = 0; i < a.size; i++ ) { output << a.ptr[ i ]; } return output;
} int main() {
Array integers1( 7 ); Array integers2; cout << integers1.getSize() << integers1; cout << integers2.getSize() << integers2; cout << "\nEnter 17 integers:" << endl; cin >> integers1 >> integers2; cout << "integers1:\n" << integers1 << "integers2:\n" << integers2; if ( integers1 != integers2 ) cout << "integers1 and integers2 are not equal" << endl; Array integers3( integers1 ); cout << integers3.getSize() << integers3; integers1 = integers2; cout << integers1; cout << integers2; if ( integers1 == integers2 ) cout << "integers1 and integers2 are equal" << endl; cout << integers1[ 5 ]; integers1[ 5 ] = 1000; cout << integers1; return 0;
}</source>
Safe array class
<source lang="cpp">#include <iostream>
- include <new>
- include <cstdlib>
using namespace std; class array {
int *p; int size;
public:
array(int sz) { try { p = new int[sz]; } catch (bad_alloc xa) { cout << "Allocation Failure\n"; exit(EXIT_FAILURE); } size = sz; } ~array() { delete [] p; } // Copy Constructor array(const array &a) { int i; try { p = new int[a.size]; } catch (bad_alloc xa) { cout << "Allocation Failure\n"; exit(EXIT_FAILURE); } for(i=0; i<a.size; i++) p[i] = a.p[i]; }
void put(int i, int j) { if(i>=0 && i<size) p[i] = j; } int get(int i) { return p[i]; }
};
int main() {
array num(10); for(int i=0; i<10; i++) num.put(i, i); for(int i=9; i>=0; i--) cout << num.get(i); cout << "\n"; array x(num); // invokes copy constructor for(int i=0; i<10; i++) cout << x.get(i); return 0;
}</source>
9876543210 0123456789"
SArray
<source lang="cpp">/* The following code example is taken from the book
* "C++ Templates - The Complete Guide" * by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002 * * (C) Copyright David Vandevoorde and Nicolai M. Josuttis 2002. * Permission to copy, use, modify, sell and distribute this software * is granted provided this copyright notice appears in all copies. * This software is provided "as is" without express or implied * warranty, and with no claim as to its suitability for any purpose. */
- include <stddef.h>
- include <cassert>
template<typename T> class SArray {
public: // create array with initial size explicit SArray (size_t s) : storage(new T[s]), storage_size(s) { init(); } // copy constructor SArray (SArray<T> const& orig) : storage(new T[orig.size()]), storage_size(orig.size()) { copy(orig); } // destructor: free memory ~SArray() { delete[] storage; } // assignment operator SArray<T>& operator= (SArray<T> const& orig) { if (&orig!=this) { copy(orig); } return *this; } // return size size_t size() const { return storage_size; } // index operator for constants and variables T operator[] (size_t idx) const { return storage[idx]; } T& operator[] (size_t idx) { return storage[idx]; } protected: // init values with default constructor void init() { for (size_t idx = 0; idx<size(); ++idx) { storage[idx] = T(); } } // copy values of another array void copy (SArray<T> const& orig) { assert(size()==orig.size()); for (size_t idx = 0; idx<size(); ++idx) { storage[idx] = orig.storage[idx]; } } private: T* storage; // storage of the elements size_t storage_size; // number of elements
};
// include helper class traits template to select whether to refer to an // ""expression template node"" either ""by value"" or ""by reference."" /* helper traits class to select how to refer to an ""expression template node""
* - in general: by reference * - for scalars: by value */
template <typename T> class A_Scalar; // primary template template <typename T> class A_Traits {
public: typedef T const& ExprRef; // type to refer to is constant reference
}; // partial specialization for scalars template <typename T> class A_Traits<A_Scalar<T> > {
public: typedef A_Scalar<T> ExprRef; // type to refer to is ordinary value
};
// class for objects that represent the addition of two operands template <typename T, typename OP1, typename OP2> class A_Add {
private: typename A_Traits<OP1>::ExprRef op1; // first operand typename A_Traits<OP2>::ExprRef op2; // second operand public: // constructor initializes references to operands A_Add (OP1 const& a, OP2 const& b) : op1(a), op2(b) { } // compute sum when value requested T operator[] (size_t idx) const { return op1[idx] + op2[idx]; } // size is maximum size size_t size() const { assert (op1.size()==0 || op2.size()==0 || op1.size()==op2.size()); return op1.size()!=0 ? op1.size() : op2.size(); }
}; // class for objects that represent the multiplication of two operands template <typename T, typename OP1, typename OP2> class A_Mult {
private: typename A_Traits<OP1>::ExprRef op1; // first operand typename A_Traits<OP2>::ExprRef op2; // second operand public: // constructor initializes references to operands A_Mult (OP1 const& a, OP2 const& b) : op1(a), op2(b) { } // compute product when value requested T operator[] (size_t idx) const { return op1[idx] * op2[idx]; } // size is maximum size size_t size() const { assert (op1.size()==0 || op2.size()==0 || op1.size()==op2.size()); return op1.size()!=0 ? op1.size() : op2.size(); }
};
int main() {
SArray<double> x(1000), y(1000); //... //x = 1.2*x + x*y;
}</source>