Welcome, Guest. Please login or register.

Author Topic: question about C++ constructors  (Read 10142 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline DaveP

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2116
    • Show only replies by DaveP
Re: question about C++ constructors
« Reply #14 from previous page: January 25, 2003, 11:30:59 AM »
/***************************************************************************
                          reference.t  -  Reference is a template class
                    that allows C++ to manage references to classes
                    as a smart pointer might, detecting when a reference
                    is destroyed and decrementing the reference count
                    on the instance. Once the reference count reaches
                    zero then the memory is cleaned up.
 
   warnings          : Crippled, reference count can wrap in certain C++ semantic conditions.
                             -------------------
    begin                :  1998
    copyright         :  
    email                :
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef  POINTER_HEADER_
#define POINTER_HEADER_

#include
#ifdef WIN32
#include
#else
#include
#endif
#include
#include
#include

#ifndef NULL
#define NULL 0x00000000
#endif

// #define _CDEBUG_ 1

//--------------------------------------------------------------------

template class Reference
{
//   Constructors and destructor

public:
Reference() : _ref(NULL) { }
Reference(T* ptr_) : _ref(ptr_) { IncrRefCount(); }
Reference(void * ptr_) : _ref((T*)ptr_)
     { if ( _ref!=NULL) IncrRefCount(); }
  Reference( const Reference &other )
  { _ref=other._ref;
    if ( _ref!=NULL )
        IncrRefCount();
  }

   virtual ~Reference()
  {
    if ( _ref!=NULL )
      DecrRefCount();
  }
   Reference & operator = ( Reference ptr_ )
   {
        if ( _ref  != NULL )
            DecrRefCount( );

        _ref=ptr_._ref;
        if ( _ref!=NULL )
          IncrRefCount();
        return *this;
   }
   Reference & operator = (T* ptr_)
   {
        if ( _ref  != NULL )
            DecrRefCount( );
        _ref=ptr_;
        if ( _ref!=NULL )
          IncrRefCount();
        return *this;
   }
   T* operator -> () { assert(_ref!=NULL); return _ref; }
   T& operator * () { assert(_ref!=NULL); return *_ref; }
   operator T* () { assert(_ref!=NULL); return _ref; }

   bool operator == (Reference ptr) { return _ref == ptr._ref; }
   bool operator != (Reference ptr) { return _ref != ptr._ref; }
   bool operator == (T* ptr_) { return _ref == ptr_; }
   bool operator != (T* ptr_) { return _ref != ptr_; }

// Shallow copy cloning, to deep copy clone override
// the clone method on Object
   static T* clone( Reference ptr )
   {
         T* retval = (T*)malloc( sizeof(T) );
         memcpy(retval,ptr._ref,sizeof(T));
         retval->clone(ptr._ref);
         return retval;
   }
   bool const isNull() { return _ref == NULL; }
   long const getRefCount() { return _ref->refcount(); }
    T* getPointer() { return _ref; }
    T* recast() { return _ref; }
   T* getPointerForceIncref( ) { IncrRefCount(); return _ref; }
   
private:
   void IncrRefCount()
   {
        if ( _ref!=NULL )
        {
#ifdef _CDEBUG_
          gBytesCount=gBytesCount+sizeof(T);
#endif
          _ref->incref( );
        }
   }
   void DecrRefCount()
   {
        if ( _ref!=NULL )
        {
#ifdef _CDEBUG_
          gBytesCount=gBytesCount-sizeof(T);
#endif
          _ref->decref( );
          if ( _ref->refcount() == 0 )
          {
             // printf("%d->del()\n",_ref);
              _ref->mark_deleted( );

              delete _ref;
#ifdef _CDEBUG_
              gFreedCount=gFreedCount+sizeof(T);
              cerr << typeid(this).name()
                   << " Active bytes:" << gBytesCount
                   << " Freed bytes:" << gFreedCount << endl;
#endif
          }
          _ref = NULL;
        }
   }
#ifdef _CDEBUG_
   static unsigned long gBytesCount;
   static unsigned long gFreedCount;
#endif
private:
    T* _ref;
};

#ifdef _CDEBUG_
template
unsigned long Reference::gBytesCount=0;

template
unsigned long Reference::gFreedCount=0;
#endif


#endif
Hate figure. :lol:
 

Offline DaveP

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2116
    • Show only replies by DaveP
Re: question about C++ constructors
« Reply #15 on: January 25, 2003, 11:33:54 AM »
/***************************************************************************
                          object.h  -  the super class of all classes
                    that can use automatic reference counting, the
                    dynamic storage operations and more.
                             -------------------
    begin                :
    copyright            :
    email                :
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef OBJECT_H
#define OBJECT_H
#include "reference.t"

class Object;
typedef Reference Object_ptr;

class Object {
public:
   Object( );
   virtual ~Object( );


    virtual Object::ReturnCode equals( Object_ptr other );
    virtual Object::ReturnCode clone( Object_ptr other );

    void Object::mark_deleted( );
    void incref( );
    void decref( );
    unsigned int refcount( );

private:
    bool iDeleted;
    unsigned int iRefCount;
};

#endif
Hate figure. :lol:
 

Offline GlaucusTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 4518
    • Show only replies by Glaucus
    • http://members.shaw.ca/mveroukis/
Re: question about C++ constructors
« Reply #16 on: January 25, 2003, 07:06:45 PM »
Okay, thanks a lot Dave!  I'll take a close look at it!

  - Mike
YOU ARE NOT IMMUNE
 

Offline FluffyMcDeath

  • Hero Member
  • *****
  • Join Date: Jun 2002
  • Posts: 3440
    • Show only replies by FluffyMcDeath
Re: question about C++ constructors
« Reply #17 on: January 27, 2003, 05:51:35 PM »
Quote

Casper wrote:
There is a saying when it comes to good programming: Allocate late, release early, i.e. you should allocate resources when you need them and release them as soon as possible.  You should not allocate stuff in the constructor unless you absolutely have to.


These are fair sentiments. That last part, allocate only what you need when you need it, is also fair.

But what the heck is a constructor then, if it doesn't allocate what it needs. If it don't construct, is it a constructor?

Perhaps this is a philosophical point, perhaps, but a constructor should lay all the necessary foundations for the use of the class.

For Glaucus, if he wants a class that opens a bunch of windows, and he wants the windows to exists from the beginning of execution until the end, then I see no problem in doing all the window allocations in the constructor.

Surrounding all your allocations a in try{} catch block is pretty much what you have to do anyway  no matter when where you allocate if you want to be graceful about it.

Perhaps I'm not getting the specific concern here.