Boost logo

Boost :

From: Bronek Kozicki (brok_at_[hidden])
Date: 2004-01-21 05:01:26


On Tue, 20 Jan 2004 22:05:33 -0500, Howard Hinnant wrote:
>
> ~D()
> ~B()
> ---
> ~B()
> ~B()
> ~B()

Ahhh, clause 5.3.5/3 : "In the second alternative (delete array) if the
dynamic type of the object to be deleted differs from its static type,
the behavior is undefined". Hm. I missed it [1].

However I still think that my example (from
http://b.kozicki.pl/cpp/T192.cpp ) :
auto_ptr<Base> source6 ()
{
  printf("returning pointer to table\n");
  return auto_ptr<Derived>(new Derived[3], del_array());
}

is valid. This is not really useful application of custom deleter, but
does not intruduce undefined behaviour, nor unexpected behaviour, thus
(being quite useless) it's still valid. Please note that deleter will
always receive static-type == dynamic-type, when used properly (ie.
smart pointer intialized directly with raw pointer).

> Therefore an interface should not imply that you can handle arrays of
> objects by simply customizing the deletion policy. Smart pointers to
> arrays of objects require a different interface, including:
>
> * no dervied-to-base conversions
> * no operator*()
> * no operator->()
> * operator[](size_t)

agree. I was not sure about first point, but example program [1]
convinced me.

> One way to accommodate this need is to create different types like:
> scoped_ptr<T>
> scoped_array<T>
> But I suggest an alternative interface (with similar functionality):
> move_ptr<T>
> move_ptr<T[]>

... which is more generic, and I like it :>>

> I guess the basic point I'm trying to make (and none to elegantly) is
> that deletion policy is an independent issue with respect to single
> object vs array interface. And so we need an elegant way to
> independently specify:
>
> 1. Deletion policy

How do we use deletion policy in C-type array? It just *has* to be
deleted with delete[], otherwise we have undefined behaviour. Well, OK,
there are some uses for deleters in C-type array, like support for
incomplete types or calling some action before actually deleting object
.. . but still it has to be deleted in a single way ... or not at all,
which also kind of deletion policy (which allows creation of "shallow
copy", and I named such policy "null deleter" in the past), hmmm...

> And I submit that:
> S<T[], my_deleter>
> is more elegant syntax than:
> S_array<T, my_deleter>

Agree. I would also add argument that its more generic
(repeating myself, sorry) ;)

B.

[1]
Slightly modifying your example will expose the problem better. Compiled
under MSVC71 and MSVC7 following program works as if everything is fine
(while its not), but under MINGW I have nice access violation error :>

#include <iostream>

struct B
{
  int i;
  virtual ~B() {std::cout << "~B()\n";}
};

struct D : B
{
  int j;
  virtual ~D() {std::cout << "~D()\n";}
};

int main(void)
{
  std::cout << "sizof(B) == " << sizeof(B) << std::endl;
  std::cout << "sizof(D) == " << sizeof(D) << std::endl;
  B* bpa = new D[3]; // ERROR!
  delete [] bpa; // ERROR!
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk