#include <iostream>
#include <stdlib.h>
//=============================================================================
class vec {
public:
double *array;
int id; // for debugging
static int ID;
int n; // size of vector
bool hold; // the object is keeping its ownership of the pointer if it's true.
vec( const vec&, const bool=false );
vec( const int&, const bool=false );
~vec();
void copy(const vec&);
void destroy();
vec& operator=(const vec&);
};
int vec::ID(1);
std::ostream& operator<<(std::ostream&, const vec&);
vec operator+(const vec&, const vec&);
//=============================================================================
vec::vec( const vec & A, const bool _hold )
{
std::cout << "begin [vec(cnst vec&)]" << std::endl;
std::cout << "_hold=" << _hold << std::endl;
id = ID++;
array = NULL;
copy( A );
hold = _hold;
}
//=============================================================================
vec::vec( const int& _n, const bool _hold )
{
std::cout << "begin [vec(cnst int&)]" << std::endl;
std::cout << "_hold=" << _hold << std::endl;
id = ID++;
n = _n;
hold = _hold;
if ( n > 0 ) {
array = new double[n];
std::cout << "[vec(n) ] Memory allocation <" << array << "> for id=" << id << " hold=" << hold << std::endl;
} else {
array = NULL;
}
}
//=============================================================================
vec::~vec()
{
std::cout << "begin [~vec() ]" << std::endl;
std::cout << "id=" << id << ", hold=" << hold << std::endl;
//if(hold){ //'if(hold)' must be removed
destroy();
//}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//=============================================================================
void vec::copy(const vec & A) //copy() changes array and n only.
{
if( A.hold ) {
if( n != A.n ) {
delete array;
array = NULL;
std::cout << "[copy(cnst vec&)] Memory deletion <" << array << "> from id=" << A.id << " to id=" << id << std::endl;
}
if( array == NULL ) {
array = new double[A.n];
n = A.n;
std::cout << "[copy(cnst vec&)] Memory allocation <" << array << "> from id=" << A.id << " to id=" << id << std::endl;
}
for( int i = 0; i < A.n; i++ ) {
array[i] = A.array[i];
}
std::cout << "[copy(cnst vec&)] Value copy <" << array << "> from id=" << A.id << " to id=" << id << std::endl;
} else {
delete array;
array = A.array;
n = A.n;
vec & _A( const_cast<vec &>( A ) );
_A.array = NULL;
_A.n = 0;
std::cout << "[copy(cnst vec&)] Memory transfer <" << array << "> from id=" << A.id << " to id=" << id << std::endl;
}
}
//=============================================================================
void vec::destroy()
{
std::cout << "destroying <" << array << ">" << std::endl;
n=0;
delete array;
array = NULL;
std::cout << "done" << std::endl;
}
//=============================================================================
vec& vec::operator=(const vec& A)// operator=() is necessary because copy constructor overwrites the value of 'hold'.
{
std::cout << "[operator=]" << std::endl;
std::cout << "arg=" << A << std::endl;
if( array != A.array ) {
copy( A );
}
return *this;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//=============================================================================
std::ostream& operator<<( std::ostream & os, const vec & A )
{
os << " (id=" << A.id << ")";
os << " (hold=" << A.hold << ")";
os << " (array=" << A.array << ")";
os << " [";
int i;
for ( i = 0; i < A.n-1; i++ ) {
os << A.array[i] << ", ";
}
os << A.array[i] << "]";
if(!A.hold){
vec& tmp( const_cast<vec&>(A) );
tmp.destroy();
}
return os;
}
//=============================================================================
vec operator+( const vec & A, const vec & B )
{
std::cout << "[operator+]" << std::endl;
std::cout << "arg1=" << A << std::endl;
std::cout << "arg2=" << B << std::endl;
if( A.hold && B.hold ) {
vec C( A.n );
for ( int i = 0; i < A.n; i++ ) {
C.array[i] = A.array[i] + B.array[i];
}
std::cout << "before return C" << std::endl;
return C;
} else if( !B.hold ) {
vec C( B );
for ( int i = 0; i < A.n; i++ ) {
C.array[i] += A.array[i];
}
std::cout << "before return C" << std::endl;
return C;
} else {
vec C( A );
for ( int i = 0; i < B.n; i++ ) {
C.array[i] += B.array[i];
}
std::cout << "before return C" << std::endl;
return C;
}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//=============================================================================
class vecUI : public vec {
public:
vecUI( int );
vecUI( const vec & );
vecUI( const vecUI & );
};
vecUI::vecUI( const vec & A ) : vec( A, true ) {
std::cout << "end of vecUI(const vec&)" << std::endl;
}
vecUI::vecUI( const vecUI & A ) : vec( A, true ) {
std::cout << "end of vecUI(const vecUI&)" << std::endl;
}
vecUI::vecUI( int _n ) : vec( _n, true ) {
}