As I have stated in my post before with a lot of links... Use the placement new operator:
 
http://lists.boost.org/boost-users/2006/07/20628.php


From: Andrew Holden [mailto:aholden@charteroaksystems.com]
Sent: Monday, July 10, 2006 20:43
To: boost-users@lists.boost.org
Subject: Re: [Boost-users] std::vector< boost::shared_ptr<int> >::pop_back()

You would manually call destructors when you do your own memory management (like std::vector).  In this case, you would also need to manually call constructors too.  Here is a modified version of your test program that doesn’t double-destruct the object.

 

class A

{

public:

      A()

      {

            counter = 0;

      }

      ~A()

      {

            counter++;

            std::cout << "~A(): " << counter << std::endl;

      }

      int counter;

};

 

int main(int argc, char* argv[])

{

      A *a;

 

      //Allocate memory using C functions, which do not call constructors

      a = (A*) malloc (sizeof (A));

      cout << a << ' ' << a->counter << std::endl;

 

      //Manually call the constructor.  The (a) tells the compiler which pointer we are initializing

      new (a) A ();

      cout << a << ' ' << a->counter << std::endl;

 

      //Manually call the destructor

      a->~A();

      cout << a << ' ' << a->counter << std::endl;

 

      //Free memory using C functions, which do not call destructors

      free (a);

      return 0;

}

 

 


From: bringiton bringiton [mailto:kneeride@gmail.com]
Sent: Monday, July 10, 2006 10:28 AM
To: boost-users@lists.boost.org
Subject: Re: [Boost-users] std::vector< boost::shared_ptr<int> >::pop_back()

 

holy! you learn something every day. you can call the destructor of an object (before destruction)

 

this is a trap for me because i dont clean up my variables in destructors.

class A {
public:
  A() {
  counter = 0;
}
~A() {
  counter++;
  std::cout << "~A(): " << counter << std::endl;
}
int counter;
};

int main(int argc, char* argv[])
{
 A a;
 a.~A();
 return 0;
}

NOTE: destructor gets called twice.

(so it's probably a good idea to NULL pointers in destructors)

 

On 7/11/06, bringiton bringiton <kneeride@gmail.com> wrote:

>>just look at the include files:

 

i looked at the header, but got a little confused.

i don't see how you can call a destruct of a a memory space that still exists. ie a C version of a vector.

 

shared_ptr<int> list[1024];

int n = 0;

 

// add an item

shared_ptr<int> newItem(new int(1));

list[n++] = newItem;

 

// remove the tail item

n--;

// destructor never called

 

is it possible to call a destructor of an object that exists?

what then happens then the object goes out of scope? the destructor will be called twice.

 

(or maybe i am completely missing the point)

 

BTW: not sure if above code compiles (did it in my head)


 

On 7/10/06, Boris Breidenbach < Boris.Breidenbach@physik.uni-erlangen.de> wrote:

On Mon, Jul 10, 2006 at 03:58:19PM +1000, bringiton bringiton wrote:
> This question is based on curiosity. How does std::vector::pop_back() call
> the destructor of the item getting removed?
>
> i understood std::vector to be a contigious array of memory, therefore an
> item's memory does not go out of scope when being popped. ie the item goes
> out of scope when the entire array goes out of scope.

just look at the include files:

bits/stl_vector.h says:
void
     pop_back()
     {
       --this->_M_impl._M_finish;
       std::_Destroy(this->_M_impl._M_finish);
     }

so the destructor is called in std::_Destroy.  Which can be found in
bits/stl_construct.h:
/**
  * @if maint
  * Destroy the object pointed to by a pointer type.
  * @endif
  */
template<typename _Tp>
   inline void
   _Destroy(_Tp* __pointer)
   { __pointer->~_Tp(); }

It just calls the destructor.

_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users