I am developing a resource manager for Neutrino 6.3, using an
extended OCB as described in the PG (“Extending Data Control Stucts”).
So I have a custom ocb_calloc () and ocb_free (), and everything works
nicely
But now, in order to fine tune the app, I need to do different initialization
of the ext. OCB (buffers and stuff) depending on the client’s open mode
(read-only, write-only or both).
Since ocb_calloc doesn’t have this information (does it?), I put all the
stuff in io_open () and made a dummy out of ocb_calloc ():
io_open ():
[...]
new_ocb = malloc ();
/* initialize new ocb depending on open mode
* (i.e. set up my buffers) */
iofunc_ocb_attach (new_ocb);
[...]
So before I continue building on this, maybe someone can help me
with my questions:
Is it okay to do OCB stuff in io_open () and pass the new OCB to
iofunc_ocb_alloc ()? Then there would be no use for a custom
ocb_calloc (), right? It would never get called…
I read about resmgr_open_bind (), do I need to call this somewhere
or does iofunc_ocb_attach () do this automatically (the docs are not
quite clear there)? In other words: is the above code sufficient?
I suggest that you view ocb_alloc() as you would view a constructor in C++. It simply allocates the memory for the OCB. The initialization for the OCB can (and actually should) be done in io_open.
Thanks Rennie! I re-read the docs and think I got it now.
Obviously, ocb_attach () calls resmgr_open_bind (), the only thing
you actually have to care about is allocating the structure (you’re
right).
I wonder why they invented ocb_calloc () then when it’s better to do
it in io_open ()…
As to your analogy with C++ constructors: IIRC, they allocate and
initialize the instance (set its initial state), but that’s OO theory – I get
the idea…
I agree that the constructor should initialize the instance. What it should not do is conditional initialization (i.e. the constructor should only perform unconditional initialization of members). Intuitively, a C++ object should have a well defined state when it is first instantiated; performing conditional initialization inside the constructor works counter to this. A C++ constructor should either yield an object with a predictable state, or it should throw an exception and yield no object - i.e. a completely destroyed object.
This is what I was getting at, since you implied that you wanted to do some conditional initialization of the ocb based on arguments to the open.
It would be wrong for ocb_calloc() to return an object with a differing internal state. It is right for ocb_calloc() to return an object with a consistent state, which then can be altered by io_open which “knows” something about how it’s state should be changed since it is (and should be) aware of the current context.