Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #11832

Re: Any way to detect the absense of virtual destructor in base class?

From "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Newsgroups comp.lang.c++
Subject Re: Any way to detect the absense of virtual destructor in base class?
Date 2011-11-26 01:36 +0100
Organization A noiseless patient Spider
Message-ID <japca2$bcp$1@dont-email.me> (permalink)
References <jal28n$gpu$1@speranza.aioe.org> <jal34c$2k7$1@dont-email.me> <4ecfdede$0$4348$7b1e8fa0@news.nbl.fi> <jap151$5an$1@dont-email.me> <4ed0171b$0$2769$7b1e8fa0@news.nbl.fi>

Show all headers | View raw


On 25.11.2011 23:30, Juha Nieminen wrote:
> Alf P. Steinbach<alf.p.steinbach+usenet@gmail.com>  wrote:
>> I'm looking at N3290, which I believe is identical to the final standard.
>>
>> And there std::unique_ptr stores a deleter, which can be function object
>> or a function pointer or whatever, specified in constructor call.
>
>    If std::unique_ptr is indeed specified to store a pointer to a deleter
> function (or a deleter object), then it's a bit disappointing.
>
>    When I read that std::unique_ptr would be a better replacement for
> std::auto_ptr, I was assuming that it's a smart pointer that is as
> efficient as a raw pointer (at least in terms of size), which destroys
> the managed object automatically (the advantage over std::auto_ptr being
> that it's safe to use in data containers such as std::vector, which may
> move its elements around when reallocating, inserting in the middle or
> eg. sorting).
>
>    However, if std::unique_ptr is (at least) the size of *two* pointers,
> it immediately becomes inferior to a raw pointer in terms of efficiency.
> While in many/most cases that doesn't matter, it's a bummer in situations
> where it would.

Yes, that is the case, sorry.

>
>    I understand the advantage of having a pointer to a deleter in the smart
> pointer object: It allows safely deleting an object even in contexts where
> the class has only been declared (rather than defined), plus some other
> situations (such as using a specialized deleter for the managed object).
> However, these situations are quite unusual in practice, and I find it
> questionable why one has to pay for something that isn't used, which goes
> against one of the core principles of C++. (After all, this principle is
> the very reason why eg. classes do not have virtual tables by default,
> but only if there specifically are virtual functions. You don't have to
> pay for what you don't use.)

I agree.


>    Or is std::unique_ptr able to elide storing a deleter pointer (eg. by
> using some kind of empty base class optimization trick) in cases where
> no deleter is explicitly specified?

I'm not sure.

Anyway I misunderstood the deleter thing. As someone pointed out on SO, 
with unique_ptr the deleter type is a template argument for the /type/. 
And it doesn't work (directly) for the usage where you allocate as 
derived and delete as base, without virtual destructor.

However, I managed to browbeat the unique_ptr functionality into doing 
that, by applying a little type erasure: :-)


<code>
#include <iostream>
#include <memory>           // std::unique_ptr
#include <functional>       // function
#include <utility>          // move
#include <string>
using namespace std;

class Base
{
public:
     Base() { cout << "Base:<init>" << endl; }
     ~Base() { cout << "Base::<destroy>" << endl; }
};

class Derived
     : public Base
{
public:
     Derived() { cout << "Derived::<init>" << endl; }
     ~Derived() { cout << "Derived::<destroy>" << endl; }
};

class BoundDeleter
{
private:
     typedef void (*DeleteFunc)( void* p );

     DeleteFunc  deleteFunc_;
     void*       pObject_;

     template< class Type >
     static void deleteFuncImpl( void* p )
     {
         delete static_cast< Type* >( p );
     }

public:
     template< class Type >
     BoundDeleter( Type* pObject )
         : deleteFunc_( &deleteFuncImpl< Type > )
         , pObject_( pObject )
     {}

     BoundDeleter( BoundDeleter&& other )
         : deleteFunc_( move( other.deleteFunc_ ) )
         , pObject_( move( other.pObject_ ) )
     {}

     void operator() (void*) const
     {
         deleteFunc_( pObject_ );
     }
};

template< class Type >
class SafeCleanupUniquePtr
     : public unique_ptr< Type, BoundDeleter >
{
public:
     typedef unique_ptr< Type, BoundDeleter >    Base;

     template< class ActualType >
     SafeCleanupUniquePtr( ActualType* p )
         : Base( p, BoundDeleter( p ) )
     {}

     template< class Other >
     SafeCleanupUniquePtr( SafeCleanupUniquePtr< Other >&& other )
         : Base( move( other ) )
     {}
};

int main()
{
     SafeCleanupUniquePtr< Base >  p( new Derived );
}
</code>


Cheers,

- Alf

Back to comp.lang.c++ | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Any way to detect the absense of virtual destructor in base class? Qi <no@no.no> - 2011-11-24 17:20 +0800
  Re: Any way to detect the absense of virtual destructor in base class? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2011-11-24 10:35 +0100
    Re: Any way to detect the absense of virtual destructor in base class? Qi <no@no.com> - 2011-11-24 21:05 +0800
    Re: Any way to detect the absense of virtual destructor in base class? Juha Nieminen <nospam@thanks.invalid> - 2011-11-25 18:30 +0000
      Re: Any way to detect the absense of virtual destructor in base class? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2011-11-25 22:25 +0100
        Re: Any way to detect the absense of virtual destructor in base class? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2011-11-25 22:40 +0100
        Re: Any way to detect the absense of virtual destructor in base class? Juha Nieminen <nospam@thanks.invalid> - 2011-11-25 22:30 +0000
          Re: Any way to detect the absense of virtual destructor in base class? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2011-11-26 01:36 +0100
            Re: Any way to detect the absense of virtual destructor in base class? Juha Nieminen <nospam@thanks.invalid> - 2011-11-26 12:16 +0000
  Re: Any way to detect the absense of virtual destructor in base class? Vladimir Jovic <vladaspams@gmail.com> - 2011-11-24 10:45 +0100
    Re: Any way to detect the absense of virtual destructor in base class? Qi <no@no.com> - 2011-11-24 21:07 +0800
  Re: Any way to detect the absense of virtual destructor in base class? SG <s.gesemann@gmail.com> - 2011-11-24 04:50 -0800
    Re: Any way to detect the absense of virtual destructor in base class? Qi <no@no.com> - 2011-11-24 21:04 +0800
      Re: Any way to detect the absense of virtual destructor in base class? Marc <marc.glisse@gmail.com> - 2011-11-24 16:12 +0000
  Re: Any way to detect the absense of virtual destructor in base class? Lee Steven <steven.mtl@gmail.com> - 2011-11-25 06:55 -0800
  Re: Any way to detect the absense of virtual destructor in base class? jgk@panix.com (Joe keane) - 2011-11-25 22:21 +0000
    Re: Any way to detect the absense of virtual destructor in base class? Ian Collins <ian-news@hotmail.com> - 2011-11-26 11:32 +1300

csiph-web