tags:

views:

351

answers:

8

I have as part of assignment to look into a development kit that uses the "two-phase" construction for C++ classes:

// Include Header
class someFubar{
public:
    someFubar();
    bool Construction(void);
    ~someFubar();
private:
    fooObject _fooObj;
}

In the source

// someFubar.cpp
someFubar::someFubar : _fooObj(null){ }

bool 
someFubar::Construction(void){
    bool rv = false;
    this->_fooObj = new fooObject();
    if (this->_fooObj != null) rv = true;
    return rv;
}

someFubar::~someFubar(){
    if (this->_fooObj != null) delete this->_fooObj;
}

Why would this "two-phase" be used and what benefits are there? Why not just instantiate the object initialization within the actual constructor?

+5  A: 

A document about Two Phase Construction.

The idea is that you cannot return a value from a constructor to indicate failure. The only way to indicate constructor failure is to throw an exception. This is not always desirable, not least because exception safety is a very complex topic.

So in this case the construction is split up: a constructor that does not throw, but also does not fully initialize, and a function that does the initialization and can return an indication of success or failure without (necessarily) throwing exceptions.

MadKeithV
The ironic thing is that more recent Symbian SDKs implement leave/trap as macros on top of try/catch.
Alex B
@MadKeithV: Thanks for your answer +1 from me.
tommieb75
+6  A: 

There is no good reason to do this - avoid. The original author of the code probably simply didn't know what they were doing.

anon
I agree with this. Exceptions exist for a reason- throw them. Especially since Construction didn't catch, so if the constructor of fooObject threw, then it wouldn't improve exception safety. In addition, this ain't camelCase Java.
DeadMG
@Neil: Heh! This is an SDK from a *huge* company, and is a constrained kit I have to say! :D Thanks for your answer! :)
tommieb75
@tommie Huge does not preclude clueless - look at MFC, for example.
anon
@Neil: True... there is a dislike for try/catch within the SDK - FYI! :D
tommieb75
@Neil, I think some platforms avoid exceptions for historic reasons. For example Symbian, where two-phase construction became so ingrained in the API, that they can't really get rid of it today, only hide behind a nicer toolkit (Qt), like COM and WinAPI behind .NET.
Alex B
@Neil: Ahhh k.... +1 from me...very good answer by the way ;P
tommieb75
+4  A: 

This is useful when you have to give the user (of your class) more control on resource allocation/deallocation. For instance think of a Socket class. The user passes in the host and port parameters to the constructor and may wish to delay the actual "opening" of the sockets (i.e, allocating the low-level SOCKET object) to a later time. He may also wish to close and re-open the Socket at will. Two-phase construction (or Lazy Initialization) facilitates this. Such a Socket interface will look like:

class Socket
{
public:
    Socket (const std::string& host, int port) : host_(host), port_(port), sock_(NULL) { }
    ~Socket () { close (); }
    void open () throw (NetworkException&) 
    {
         sock_ = new_low_level_socket (host_, port_);
    }
    void close ()
    {
       if (sock_)
       {
          close_low_level_socket (sock_);
          sock_ = NULL;
       }
    }
  // private members
};

// Usage:

ing
main ()
{
    Socket sock ("www.someurl.com", 80);
    sock.open ();
    // do something with sock
    sock.close ();
    // do something else
    sock.open();
    // do something with sock
    return 0; 
    // sock is closed by destructor.
}

BTW, this idiom is not a replacement for preventing exceptions from being thrown from the constructor. If the constructor fails, throw an exception. For more information, please see this BS FAQ and the entry at C++-FAQ-Lite.

Vijay Mathew
@Vijay: Good Example! :) +1 from me.
tommieb75
@Pete Thanks for pointing this out. Fixed.
Vijay Mathew
A: 

I certainly wouldn't be a fan of this two step construction. There's loads of other ways to get around raising an exception/error in a constructor. Firstly any C++ compiler worth it's weight should be able to throw an exception from a constructor and allow it to be caught appropriately.

Another solution would be to have an internal error code similar to the posix errno approach. And the caller could then query this error code through a call to a member of the class. IIR Windows has something like this with the GetLastError function.

toby
@toby: Sorry to be blunt but -1 from me... you have to take into account of reading other comments, this is on an embedded platform, my hands are tied, cannot do anything about it despite the compiler being a iffy one....and for the sake of getting the job done... you seem to be too harsh in "*any C++ compiler worth it's weight*", sorry, if you're working on embedded systems then that comment is irrelevant...
tommieb75
@tommieb75: Sorry you feel that way, but at the time I wrote the answer nowhere in your original question or in *any* comment did it mention that you were dealing with an embedded platform.
toby
@Toby: that's ok... Alex B did put his finger on the comment around the same time you answered... "I think some platforms avoid exceptions for historic reasons. For example Symbian" in response to Neil's answer above. :) That was absolutely spot on. :)
tommieb75
+1  A: 

The source given is bizarre in the extreme.

If it is C++, then new cannot return 0, and should throw an exception.

If it is something not entirely unlike C++ where new returns 0 on failure (such things have been known to exist), then Construction is equivalent to:

bool someFubar::Construction(){ // no need for void in C++, it's not C
    delete _fooObj;             // nothing stops this getting called twice!
    _fooObj = new fooObject();  // no need for this->, it's not Python
    return _fooObj;             // non-zero is true 
}

someFubar::~someFubar(){
    delete fooObj;              // it's OK to delete NULL in C++. 
}

Now we have a problem - if Construction is called twice, do we construct it again and return true as above, don't construct it again and return true as it's constructed, or don't construct it again and return false as it's an error to construct something twice?

Sometimes - for example for classes which manage external resources - you may want to implement them as a state machine which you create, then allocate the resource. This is reasonable where a resource can become invalid, so you would have to check the operations you perform on it anyway. Providing a conversion from the type to bool is the pattern using in the standard library for such resources. Normally you should construct an object in one go and expect it to be valid.

Pete Kirkham
Every C++ compiler I have ever seen has a no throw new option, and the ability to disable exceptions. Claiming that new can not return 0 is a bit hyperbolic.
stonemetal
@Pete: I agree with the last sentence but... *shrugs* what can I do...the standard for that embedded platform dictates that... nowt I can do about that... but +1 from me for your answer :)
tommieb75
@stonemetal the code does not say `_fooObj = new (nothrow) fooObject();`
Pete Kirkham
+2  A: 

Sometimes you have to use C++ without exceptions enabled. In that situation, the lack of a return value from a constructor makes life difficult, so you have an explicit construction function that you can test for success instead.

Kylotan
+1  A: 

Why would this "two-phase" be used and what benefits are there?

This idiom is used for two reasons:

  • to separate the initialization into two different parts: the part that is always stable and will not fail (left in constructor) and the part that may fail (the separate construction function).

This idiom has been used in the past before the usage of exceptions was standardized in the language, and by library designers who didn't understand (or for some reason didn't want to use) exceptions.

You will still find it in legacy/backwards-compatible code (e.g. MFC).

  • to implement "virtual construction". Basically, you declare your Construction member function as (pure) virtual and allow specialized classes to replace it. This is almost always [1] a sign or poor design (you can and should implement your code so that you don't need this idiom).

[1] - "almost always" means here that I see no reason at all for doing it but I may be missing something :).

utnapistim
+1  A: 

A reason for doing this might be that constructors don't return any values. Some persons prefer doing a Create like function that should be called after object instantiation. In case you're not using exception because they create a lot of code (especially in the embedded world) it is impossible to use just the constructor because it doesn't offer any guarantees (like I said, it cannot return any values).

Other technique that I saw was something like this:

XObject* o = new XObject();
o->IsOk();

It basically does the construction inside the constructor and holds the result of the operation inside a variable - not space efficient.

Iulian Şerbănoiu