Release() and how that works...

Started by
18 comments, last by Cyelince 22 years, 1 month ago
Okay, I was wondering, how the Release() thing works found so often in the DirectX Interfaces...I noticed, you never ''delete'' them. You just Release() and make them NULL. I made a class like that and did some tests. Anyone else know if this is actually valid or not? I didn''t include the #includes though...
  
class MemTestR
{
public:
   MemTestR(): m_ref(1) {};

   int Release()
   {
      int tmp = --m_ref;

      if(m_ref<=0)
         delete(this);

      return(tmp);
   }

   int m_ref;
   int m_x, m_y;
};

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

//

//

// main()

//

//

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


int main()
{
   {
      MemTestR * mtr = NULL;

      mtr = new MemTestR;

      mtr->m_x = 0;
      mtr->m_y = 0;

      printf("\nX:%i\nY:%i\nRef:%i\n", mtr->m_x, mtr->m_y, mtr->m_ref);

      int tmp = mtr->Release();

      printf("\nX:%i\nY:%i\nRef:%i\n", mtr->m_x, mtr->m_y, tmp);//mtr->m_ref);

   }

   /// doesn''t work if you don''t make it a pointer...

   {
      MemTestR mtr;

      mtr.m_x = 0;
      mtr.m_y = 0;

      printf("\nX:%i\nY:%i\nRef:%i\n", mtr.m_x, mtr.m_y, mtr.m_ref);

      int tmp = mtr.Release();

      printf("\nX:%i\nY:%i\nRef:%i\n", mtr.m_x, mtr.m_y, tmp);//mtr->m_ref);

   }

   printf("\n\nDone\n");

   return(0);
}

  
Advertisement
ok, the release function has one purpose and one purpose alone, to release directdraw (possibly D3D) surfaces, before you exit the program you have to "release" all of the surfaces you created.

,Matt

-= kill one your a murderer, kill thousands your a conquerer =-

Edited by - samosa on February 17, 2002 10:32:11 PM
-= kill one you're a murderer, kill thousands you're a conquerer =-
I would recommend you to have a look at the "reference counting" subject in a good C++ book, like Scott Meyers'' "Effective C++"... Also, look up COM in the MSDN.



Laurent - http://www.lafaqmfc.com/
My little game: http://www.lafaqmfc.com/starshooter.htm
Thank you for you input, samosa.

However, I am aware of the reason of Release(). I know it ''releases'' the surfaces and other things. But in releases a surface, dosn''t that deallocate the memory? And therefore call delete or free or whatever on the object itself? I would like to make a class, or interface, or some other object that can delete itself when it needs to (the reference count has gone down to 0).

Or does DirectX just create all the stuff somewhere else, and calling Release() just delete that stuff where it exists? I am really interested in what they did you accomplish that. It seems to work in the test program I posted up here.

Cocyen
Thanks Laurent. I will definitely check Effective C++ out. It seems like a great idea, so you can have a ton of things pointing to 1 object and each one releases it and it finally does away with itself when it''s count is 0.

By the way...you mentioned COM. While I know DirectX cuddles up to that...is the Release() something that you couldn''t do without COM or what? I am still going to check the book out, but I''d rather steer away from programming something with COM.

Cocyen
I thought everything in a program was destroyed as soon as you quit the application... I still use the Release() functions, but is it really needed? Or is that why I kept getting the same palette when I ran the program again even when I never set it in the first place. Bah! Whatever. BSTS.
---Will DDR for food.
Well, that is amusing about the palette...however, if you have like a big 3D game and huge levels with 50 or so MB of data, chances are you are going to want to free some of that data before you load in the next level (or stream in parts of another area). So you will be releasing and creating the data over and over. And if you never cleared the data it would all just pile up and crash the program or something.


- Cocyen
COM uses reference counting, which is why you call Release() (which will call delete if necessary), but there is no reason you cannot add reference counting in your own classes.

It is COM which needs Release, not the other way round.

By the way, since we are talking about ref-counting, you can implement your own smart pointer class which would call Release automatically when you assign them another value.

e.g. (just a proof of concept, probably full of bugs)

  template<class Pointee> // Make a pointer to PointeeSmartPointer{private:  Pointee* ptr;public:  SmartPointer() : ptr( NULL ) {};  SmartPointer( Pointee* _ptr, bool addref = true )  : ptr( _ptr )  {    // COM objects already have their reference count    // incremented when you get them, so, if you want    // the smart pointer to ''take over'', the reference    // stored in the C pointer, you do not increment    // again (addref=false).     if( ptr && addref ) ptr->AddRef();   }  ~SmartPointer()  {    if( ptr ) ptr->Release();  }  SmartPointer( const SmartPointer<Pointee>& other )  : ptr( other.ptr )  {     if( other.ptr ) other.ptr->AddRef();  }  SmartPointer<Pointee>&  operator=( const SmartPointer<Pointee>& other )  {    if( ptr == other.ptr )      return *this;    // Note: always AddRef before Release    if( other.ptr ) other.ptr->AddRef();    if( ptr ) ptr->Release()    ptr = other.ptr    return *this;  }  Pointee& operator*() { return *ptr };}  
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Hmmm, Samosa is wrong on this one.

DX is based on COM, all Release calls are COM, and not related specifically to surfaces or whatever the object can be.

I had no time to try to compile Fruny''s class, but this one looks very good to me It shows nicely what reference counting is and how good it can be.


Laurent - http://www.lafaqmfc.com/
My little game: http://www.lafaqmfc.com/starshooter.htm
That does look like a good class. I haven''t worked with templates much though. I''m going to get the Service Packs first since I hear that is a place MSVC++ has a bit of problems with. However...what about the Release() method, could someone show me an example how one inside a class. Or if this one is valid (that I posted earlier)?

  class MemTestR{public:   MemTestR(): m_ref(1) {};   int Release()   {      int tmp = --m_ref;      if(m_ref<=0)         delete(this);      return(tmp);   }   int m_ref;   int m_x, m_y;};  

This topic is closed to new replies.

Advertisement