Welcome, Guest. Please login or register.

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

Description:

0 Members and 1 Guest are viewing this topic.

Offline DaveP

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2116
    • Show all replies
Re: question about C++ constructors
« on: January 24, 2003, 07:48:58 AM »
Mike

I think you should seriously consider - where possible - using auto or smart points during memory allocation.

Firstly I would never throw an exception in a constructor.

What would be better would be to use a static method on the class to be the factory for the object, this then has permission to inspect the interior of the class to see that all allocations have gone well - as well as being the right place to throw an exception.

#include
#include

class MyClass : public HisClass
{
 public:
       MyClass( )
       {
            iGoToTheTopOfTheClass=new CheeseClass();
       }

       static Reference createMyClass( )
       {
               Reference cReturnable=new MyClass( );
               if ( cReturnable->iGoToTheTopOfTheClass==NULL )
                      throw new HolyMackeralsBatmanException( );

              return returnable;
       }
 
private:
    Reference< CheeseClass> iGoToTheTopOfTheClass; // autopointer template called Reference
};

Because the autopointer goes out of scope as soon
as the stack unwindes it deletes the MyClass instance which causes the iGoToTeTopOfTheClass autopointer to go out of scope.

The autopointer for  iGoToTheTopOfTheClass will check the contents of memory itself and see that it doesn't need to deallocate that.

By doing it this way not only do you need to worry about deallocation during a stack unwind or the messy business of supporting exception throwing on a constructor but you have nicely introduced yourself to the concepts of "Homes" and "Factories" for object instances so beloved of Distributed OO.
Hate figure. :lol:
 

Offline DaveP

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2116
    • Show all replies
Re: question about C++ constructors
« Reply #1 on: January 24, 2003, 09:36:24 AM »
Ive done a more generic method than this in the past for
memory pointers to system objects. The Void object contains a pointer
to a memory are or NULL, the application writer uses Reference
smart pointer templates during normal use.

For memory that you own at a given point you call the Void.own( )
method ( and then when the reference count reaches zero the memory
is delete-d ) and if you decide you no longer own it you can call
Void.disown( ) and the pointer will still be valid but will no
longer assume that it needs to be cleared up when the Void( )
destructor is called by the Reference reference count
getting to zero.

Then anything specific that the application does not always
own  is a specialisation ( like a Window class ) of that Void class.

Pick and choose from the methods or even invent your own. Thankfully
we might not have freedoms as we used to but we certainly have
freedom in programming style.
Hate figure. :lol:
 

Offline DaveP

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2116
    • Show all replies
Re: question about C++ constructors
« Reply #2 on: January 25, 2003, 11:26:31 AM »
"By using your Reference template you can dynamically allocate classes and be assured that when the reference goes out of scope the referenced class will then be deallocated - assuming there was only one reference to begin with."

Correct, with the caveat that reference counting is 1-1 with the object instance so multiple references can exist and the last reference to go out of scope will be the one that deletes the object - unless you force the reference count to increment ( which I have
had to make provision for because VissyC does not handle C linkage function pointers with classes properly ).

" I assume the destructor for the Reference template class would delete the wrapped object? Is this correct???"
If it is the last one out.

" Can I have the source to this? It might more sense if I just look at the code."

yep. Ill post it in a bit when I make sure there are no confidential bits left, and Ill throw in a GPL statement.

Note that the style I use some don't like because it requires provision that the objects that it reference to implement a few methods :- incref, decref, clone ( for deep copy cloning ) and equals ( for value types ).

My top level superclass is called Object which if you really care what it does I will put under GPL and post here too.

Back in a mo....
Hate figure. :lol:
 

Offline DaveP

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2116
    • Show all replies
Re: question about C++ constructors
« Reply #3 on: 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 all replies
Re: question about C++ constructors
« Reply #4 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: