C++ Tutorial/Data Types/Your array

Материал из C\C++ эксперт
Перейти к: навигация, поиск

creates a safe array class.

#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;
}

Define your own array class

#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;
}

Safe array class

#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;
}
9876543210
0123456789"

SArray

/* 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;
}