Boost logo

Boost :

From: Julio M. Merino Vidal (jmmv84_at_[hidden])
Date: 2006-08-23 11:40:52


Hello everybody,

At the moment, some objects in the preliminary Boost.Process library
are only constructed internally by the library. Examples of these
include 'status' instances, created by calls to 'child::wait', and
instances of 'child', created by 'launcher::start'. This is currently
done by declaring friendship among the related classes (well, not
exactly, but almost).

I believe this is suboptimal because it prevents extensibility.
Consider a user that wants to create his own Launcher implementation.
His code is required to return a new 'child' object. But, oh! He
cannot currently create it because the constructor is private and his
launcher class is not a friend of the provided 'child'. Of course, he
could implement his own 'child' -- and in turn implement his own
'status'. Ouch.

In order to solve this, I was now adding some free functions that call
the appropriate constructors. This way, the class' constructor is
kept private to avoid "accidental" creations from user code, but the
user still has the ability to create such objects when he really wants
to. For example:

class status {
protected:
    status(int flags);
    friend status create_status(int flags);
...
};

inline
status
create_status(int flags)
{
    return status(flags);
}

The first thing I'm wondering is if this design approach makes sense
or I should simply make the constructor public. No matter the answer,
the following still applies.

But then, there is a worse problem (which made me write this mail in
the first place). Consider the child's constructor:

class child {
protected:
    child(handle_type h,
          detail::file_handle fhstdin,
          detail::file_handle fhstdout,
          detail::file_handle fhstderr);
    friend child create_child(handle_type h,
                              detail::file_handle fhstdin,
                              detail::file_handle fhstdout,
                              detail::file_handle fhstderr);
};

So far so good: the create_child function can now be used by the
user... except that... he now has to deal with the file_handle class
which was kept completely private until now. So a couple of questions
arise:

1) Should the user be allowed to construct these classes (for the reasons
   explained above)?

2) If 1 is "yes", then file_handle (and any other class that appears in other
   create_* functions) needs to be made public. This exposes some classes
   that are not really about "process management" to the user, but maybe
   that is not a problem? Eventually these classes may end up being part
   of some other library that deals with low-level OS stuff (Boost.System?).

I'm open to other suggestions.

Thanks.

PS: If this message does not belong to this list, please tell me and
forgive the inconvenience.

-- 
Julio M. Merino Vidal <jmmv84_at_[hidden]>
The Julipedia - http://julipedia.blogspot.com/

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk