Re: Class design philosophy
On 13 Feb 2007 06:52:52 -0800, "HMS Surprise" <john@datavoiceint.com>
wrote:
I am setting up a virtual class of IO devices and one derivative is a
USB Hid device. My mentor and I are debating whether opening the
device should be part of the ctor. He thinks opening should be a
function called after construction. I was thinking the constructor
should open the device and fail if it is not found. Also after it is
found memory must be allocated for the input buffer. Though allocating
a kilobyte of memory should not fail there are several things that
could make the device unavailable. Thus I see no advantage of
constructing a device and then possibly not be able to open it for IO.
I suppose I could have multiple constructors but really don't like to
keep up with multiple parameter sets.
Would appreciate your thoughts on what is convention and/or practical.
This is the old single vs. two phase construction argument. The latter used
to be common when C++ lacked exceptions, because there was no way to report
an error from a constructor. The problem is, an object is supposed to be
fully alive once constructed, but two-phase construction requires an extra,
post-construction step, and before you perform it, it's possible to call
all the member functions. To be robust, every member function then has to
check if the object is fully initialized and perhaps lazily initialize it
or report an error in some way. On the other hand, two-phase construction
makes it easier to write code like this:
X x;
if (whatever)
x.init(a, b);
else
x.init(c, d, e);
Single-phase construction tends to require code like this:
std::auto_ptr<X> px;
if (whatever)
px.reset(new X(a, b));
else
px.reset(new X(c, d, e));
But this isn't very common. MFC's CWnd uses two-phase construction, and
there is actually a reason for this beyond the absence of exceptions 15
years ago. As you may know, CWnd is a wrapper class for the Windows HWND,
and HWND objects exist independently of CWnds. For things like dialog
boxes, which create their HWNDs all in one go based on resource templates,
it makes a lot of sense for CWnd to forgo creation of HWND in its ctors and
provide attachment/deattachment semantics instead.
--
Doug Harrison
Visual C++ MVP