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


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

Re: Virtual functions in constructors. Is it possible?

From Leo Equinox Gaspard <ekinox1995@gmail.com>
Newsgroups comp.lang.c++
Subject Re: Virtual functions in constructors. Is it possible?
Date 2011-07-05 19:55 +0200
Organization A noiseless patient Spider
Message-ID <iuvj59$s8m$1@dont-email.me> (permalink)
References (9 earlier) <iut4g4$jio$1@dont-email.me> <iutd2n$d9m$1@dont-email.me> <iuuk44$i31$1@dont-email.me> <iuurn9$sck$1@dont-email.me> <iuv17c$uog$1@dont-email.me>

Show all headers | View raw


Le 05/07/2011 14:51, Alf P. Steinbach /Usenet a écrit :
> * Leo Equinox Gaspard, on 05.07.2011 13:15:
>> Oh. I thought the exception was in Init().
>> The run of the program I figured was :
>>
>> => new Derived()
>> => Instantiation of an Initializer
>> => Only do it, we don't want *any* exception in this constructor
>> => End of new
>> => ~Initializer()
>> => Call to Init(), catching exceptions
>> => Init() does the whole construction stuff, additionnally calling
>> Base's Init()
>> => If any exception was caught, then clear the work done by Init()
>> using InitFailed()
>> => InitFailed() should be exception-less and make the object ready to
>> be destructed.
>> => Then rethrow the exception
>> => End of ~Initializer
>> => If any exception is thrown, then the object is not valid, and hence
>> should
>> not be used, but immediately destructed. That's the default behavior
>> of the
>> exception, which will make any scoped items to be deleted.
>> Of course, using a raw pointer will lead to memory leaks, but that's
>> always as
>> it with them plus exceptions.
>>
>> Where am I mistaking ?
>
> Instead of me explaining *again*, try out the given code. You can use
> compiler switch "-D" to define a macro symbol.
>
> Cheers & hth.,
>
> - Alf
>

I *did* try it.
And, as soon as I change it to reflect what I mean - this means removing the
FAIL_CONSTRUCTOR case and adding a InitFailed() -, everything works OK. BTW
the NO_INIT_CALL looks useless to me, so I removed it.
And, for the -D switch, thanks, but I knew it.
Please also note that InitFailed doesn't has any use, but it could be 
used in
case of raw pointer manipulation.
The code (you only have to play with FAIL_INIT) :
<code>
#include <iostream>
#include <stdexcept>
#include <cstdlib>
#include <memory>
using namespace std;

namespace g {
     int nObjectsAllocated  = 0;
}    // namespace g

class VirtualBase {
protected:
     class Initializer;
     friend class Initializer;

     class Initializer {
     public:

         Initializer() {
             cout << "Initializer" << endl;
             p = 0;
         }

         ~Initializer() {
             cout << "~Initializer" << endl;
             try {
                 if (p)
                     p->Init(); // call the virtual function
             } catch (...) {
                 p->InitFailed();
                 throw;
             }
         }
         // might be private if VirtualBase is declared as friend...

         void Register(VirtualBase* b) const {
             p = b;
         }
     private:
         mutable VirtualBase* p;
         // private and not implemented
         Initializer(const Initializer&);
         void operator =(const Initializer&);
     };
public:

     VirtualBase(const Initializer& i) {
         cout << "VirtualBase" << endl;
         i.Register(this);
     }
private:
     virtual void Init() = 0;
     // will be called immediately after the constructor
     // of the most derived class

     virtual void InitFailed() = 0;
     // will be called if Init failed. Should leave the object
     // in a destructable state.
};

// This is the actual hierarchy

class Base : public virtual VirtualBase {
public:

     static void* operator new( size_t size )
     {
         cout << "Allocation" << endl;
         ++g::nObjectsAllocated;
         return ::operator new( size );
     }

     static void operator delete( void* p )
     {
         cout << "Deallocation" << endl;
         --g::nObjectsAllocated;
         return ::operator delete( p );
     }

     Base(const VirtualBase::Initializer& i = Initializer()) : 
VirtualBase(i) {
         cout << "Base" << endl;
     }

     ~Base() {
         cout << "~Base" << endl;
     }

     void Init() {
         cout << "Base::Init()" << endl;
         #ifdef FAIL_INIT
             throw runtime_error( "Oops, `Init` failed." );
         #endif
     }

     void InitFailed() {
         cout << "Base::InitFailed() - could do something if needed" << 
endl;
     }
};

int main()
{
     int result = EXIT_FAILURE;
     try
     {
         auto_ptr<Base> p(new Base);  // calls Base::Init.
         // We *need* an auto_ptr to ensure that the item will be
         // deleted in case of exception.
         result = EXIT_SUCCESS;
     }
     catch( exception const& x )
     {
         cerr << "!" << x.what() << endl;
     }

     if( g::nObjectsAllocated > 0 )
     {
         cerr << "!Memory leak." << endl;
     }
     cout << "Finished." << endl;
     return result;
}
</code>

So I must repeat my question : Where am I mistaking ?

Cheers,
Leo

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


Thread

Virtual functions in constructors. Is it possible? Anonymous <anonymous@no.net> - 2011-07-02 00:19 +0200
  Re: Virtual functions in constructors. Is it possible? "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-07-02 00:37 +0200
    Re: Virtual functions in constructors. Is it possible? Anonymous <anonymous@no.net> - 2011-07-02 01:19 +0200
      Re: Virtual functions in constructors. Is it possible? "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-07-02 08:50 +0200
        Re: Virtual functions in constructors. Is it possible? Anonymous <anonymous@no.net> - 2011-07-02 10:50 +0200
          Re: Virtual functions in constructors. Is it possible? "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-07-02 11:17 +0200
            Re: Virtual functions in constructors. Is it possible? Anonymous <anonymous@no.net> - 2011-07-02 11:25 +0200
              Re: Virtual functions in constructors. Is it possible? Anonymous <anonymous@no.net> - 2011-07-02 11:31 +0200
              Re: Virtual functions in constructors. Is it possible? "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-07-02 12:00 +0200
              Re: Virtual functions in constructors. Is it possible? Werner <werasm@gmail.com> - 2011-07-04 01:10 -0700
                Re: Virtual functions in constructors. Is it possible? Anonymous <anonymous@no.net> - 2011-07-04 20:41 +0200
                Re: Virtual functions in constructors. Is it possible? "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-07-04 21:35 +0200
                Re: Virtual functions in constructors. Is it possible? Leo Equinox Gaspard <ekinox1995@gmail.com> - 2011-07-04 23:59 +0200
                Re: Virtual functions in constructors. Is it possible? "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-07-05 11:09 +0200
                Re: Virtual functions in constructors. Is it possible? Leo Equinox Gaspard <ekinox1995@gmail.com> - 2011-07-05 13:15 +0200
                Re: Virtual functions in constructors. Is it possible? "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-07-05 14:51 +0200
                Re: Virtual functions in constructors. Is it possible? Leo Equinox Gaspard <ekinox1995@gmail.com> - 2011-07-05 19:55 +0200
                Re: Virtual functions in constructors. Is it possible? Anonymous <anonymous@no.net> - 2011-07-05 20:46 +0200
                Re: Virtual functions in constructors. Is it possible? "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-07-05 21:23 +0200
                Re: Virtual functions in constructors. Is it possible? Werner <werasm@gmail.com> - 2011-07-06 00:14 -0700
  Re: Virtual functions in constructors. Is it possible? Virchanza <virtual@lavabit.com> - 2011-07-05 14:58 -0700
    Re: Virtual functions in constructors. Is it possible? "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-07-06 01:28 +0200

csiph-web