Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualBregma

Posted 12 January 2013 - 10:17 PM

Using the non-OO method of two-phase creation means you can not have class invariants to help you reason about your code.  You are in effect using procedural idioms.  Do not fool yourself into thinking otherwise.

 

It is possible to maintain a class invariant in a procedural manner if you ignore the object state in between creation and initialization and between tear-down and deallocation, and you add state checking to each and every access (so, every member function needs to endure the state of the object is valid, ie. the invariants are true.  Or, like most production code, you just ignore error states and the the OS clean up on crashes --  this is the 'simpler than throwing an exception' method).

 

Here's another set of data points for your consideration.

  • All members are initialized in the constructor regardless of your intentions, and the 'initializer' only assigns the members new values later.  That's fine if all your members are held by pointer, but otherwise you've just increased the construction cost -- and given the new operator is very expensive you might want to reconsider always holder members by pointer.
  • Using procedural methods of object construction prevents the effective use of RAII, the singlemost powerful and useful idiom in C++.
  • Procedural initialization means explicitly chaining initializers up the class heirarchy.
  • Procedural initialization has a much greater potential for resource leaks, since you need to check and manually unwind on failure.  See above about holding members by pointer.
  • Procedural initialization requires either convoluted if-blocks or (preferrably in this case) cascading gotos for any non-trivial classes.  Or you just use the method that's simpler than throwing an exception.

Two-phase destruction of objects is even more problematic, especially in terms of resource leakage.  That's just lunacy gone mad.

 

If your standards require that you write more code than necessary and that you write more error-prone code, you might be doing it wrong.  If your standards require you write code that makes it harder to reason about the internal state of your program and makes it harder for another programmer to come along and pick up on what's going on, it might be failing to fulfill its main purpose.

 

By the way, if you're using a compiler that conforms to the C++ standard, unform initializers let you initialize arrays and even std::vectors in a constructor without the need for default constructors.


#1Bregma

Posted 12 January 2013 - 10:15 PM

Using the non-OO method of two-phase creation means you can not have class invariants to help you reason about your code.  You are in effect using procedural idioms.  Do not fool yourself into thinking otherwise.

 

It is possible to maintain a class invariant in a procedural manner if you ignore the object state in between creation and initialization and between tear-down and deallocation, and you add state checking to each and every access (so, every member function needs to endure the state of the object is valid, ie. the invariants are true.  Or, like most production code, you just ignore error states and the the OS clean up on crashes --  this is the 'simpler than throwing an exception' method).

 

Here's another set of data points for your consideration.

  • All members are initialized in the constructor regardless of your intentions, and the 'initializer' only assigns the members new values later.  That's fine if all your members are held by pointer, but otherwise you've just increased the construction cost -- and given the new operator is very expensive you might want to reconsider always holder members by pointer.
  • Using procedural methods of object construction prevents the effective use of RAII, the singlemost powerful and useful idiom in C++.
  • Procedural initialization means explicitly chaining initializers up the class heirarchy.
  • Procedural initialization has a much greater potential for resource leaks, since you need to check and manually unwind on failure.  See above about holding members by pointer.
  • Procedural initialization requires either convoluted if-blocks or (preferrably in this case) cascading gotos for any non-trivial classes.  Or you just use the method that's simpler than throwing an exception.

Two-phase destruction of objects is even more problematic, especially in terms of resource leakage.  That's just lunacy gone mad.

 

If your standards require that you write more code than necessary and that you write more error-prone code, you might be doing it wrong.  If your standards require you write code that makes it harder to reason about the internal state of your program and makes it hardware for another programmer to come along and pick up on what's going on, it might be failing to fulfill its main purpose.

 

By the way, if you're using a compiler that conforms to the C++ standard, unform initializers let you initialize arrays and even std::vectors in a constructor without the need for default constructors.


PARTNERS