C++ Tutorial/Data Types/Your array

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

creates a safe array class.

<source lang="cpp">#include <iostream>

  1. include <new>
  2. 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;

  1. include <iomanip>

using std::setw;

  1. 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>

  1. include <new>
  2. 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.
*/
  1. include <stddef.h>
  2. 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>