Re: Creating an object that is read from an input stream.

From: Jason Heyes (geoffhys_at_optusnet.com.au)
Date: 12/15/03


Date: Mon, 15 Dec 2003 15:36:29 +1100


"David White" <no@email.provided> wrote in message
news:vR5Db.5481$xm.158426@nasal.pacific.net.au...
> "Jason Heyes" <geoffhys@optusnet.com.au> wrote in message
> news:3fdc2284$0$18388$afc38c87@news.optusnet.com.au...
> > Exceptions are annoying. I like streams better.
>
> They aren't interchangeable.
>

I know.

> >
> > Let me ask you something. Should every class have a default constructor?
>
> No.
>
> > Should the Box class have a default constructor?
>
> I wouldn't find it useful without one.
>

What do you mean "useful"?

>
> > You say the default
> > constructor can create a Box that is valid. But how do you decide on
which
> > Box to create?
>
> Whatever you like. A "unit Box" - 0,1,1,0 - is the obvious default, just
as
> zero is the obvious default for type int (and is what you get is you write
> int()).
>

What about the box centered at the origin -1,1,1,-1? Isn't that an obvious
default to use?

>
> > What I am saying is that sometimes it doesn't make sense to
> > have a default constructor. Do you agree?
>
> Yes, but not in this case. If you have a default constructor the stream
code
> is quite simple. Without one it's unnecessarily complicated.
>

The stream code is almost the same. The main difference is that you need

    std::istream &operator>>(std::istream &, Box *&);

to read the first Box.

>
> Not having a default constructor can be a real pain sometimes. If you have
a
> Box as a member of another class and there is no default constructor, the
> class is forced to initialize it somehow in its own constructor, even if
it
> won't know what values it's supposed to have until later. In general, if
> there's a reasonable default, I'd have a default constructor. It just
makes
> life easier.
>

And if there isn't a reasonable default, you start to think that there is
something wrong with your class. What's worse is when you have a default
that doesn't make any sense, and your are using it throughout your program.

>
> >
> > I don't know what Rectangle class you are referring to.
>
> For example, for a graphics library of mine I wrote two rectangle classes.
> One is LogRect, or "logical rectangle" which represents the logical, or
> integer, units on the graphics device on which drawing takes place. The
> other is VirRect, or "virtual rectangle", which represents a
floating-point
> scale of the user's choice. All drawable objects are defined in virtual
> units, which are later converted to logical units for drawing. Within the
> library source code, the type 'LogRect' appears 623 times, and the type
> 'VirRect' appears 902 times. These objects are used everywhere. Using them
> would have been extraordinarily difficult if they didn't have default
> constructors. To give just one example, the base class of all drawable
> objects has two VirRects and one LogRect. It is not known what values some
> or all of these rectangles will have until after the drawable object is
> created.
>

If you declare objects as you use them, you won't have a problem. For
instance, rather than write

    Box box;
    // code fragment
    box = whatever;

you can write

    // code fragment
    Box box = whatever;

This way you don't abuse the default constructor.

>
> > The Box class is very simple.
>
> It's the simple classes that tend to be used the most, and for which a
> default constructor is most useful.
>

Even for simple classes such as Box, however, a default constructor is a bad
idea.

>
> > You can read and write Boxes using streams and get the area of
> > a Box. You cannot create a Box without reading it from a stream. Is that
> so
> > wrong?
>
> If that's what suits your purpose, no, but it's not something I can
imagine
> ever wanting.
>

It doesn't have to be Boxes that you read and write. It could be an image
file like a TGA, GIF, BMP, etc.

>
> > If you want you can modify the class to have this:
> >
> > Box::Box(int l, int r, int u, int d) : left(l), right(r), up(u), down(d)
> > {
> > if (!validate(l, r, u, d))
> > throw std::runtime_error("Invalid arguments");
> > }
> >
> > It still doesn't solve my initial problem. How will you read your first
> Box
> > object from a stream?
>
> Box b;
> if(is >> b)
> {
> // whatever
> }
>
> DW
>

You create a default Box and then write straight over it. The default Box
was never used. Therefore it should never have been created. Here is a
correct version that does not use the default constructor:

int l, r, u, d;
if (is >> l >> r >> u >> d)
{
    Box b(l, r, u, d);
    // whatever
}



Relevant Pages

  • Re: Pattern suggestion for processing similar image types
    ... This approach would constrast with a trivial constructor ... Therefore I think your concerns are really those of the "factory" object ... If the stream used to instantiate the PGM is unique the the ...
    (comp.object)
  • Re: throwing exception from constructor
    ... This would create a three-state stream - closed, ... appropriate arguments to the FileStream constructor. ... one calls the static method rather than using the constructor, ... extra complexity, ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Creating an object that is read from an input stream.
    ... >> You can throw an exception if that happens. ... The default constructor can create a Box that's valid. ... If you have a default constructor the stream code ... > I don't know what Rectangle class you are referring to. ...
    (comp.lang.cpp)
  • Re: put data in InputStream
    ... <SNIP> ... > to the inputstream? ... I suspect another reason an input stream is ... linked / associated with a data source via a constructor is because it is ...
    (comp.lang.java.help)
  • How ObjectInputStream.readObject Works
    ... readObject seems to have magical properties of being ... public no-arg constructor; otherwise, if the class is Serializable, it ... Serializable Object will not be invoked, but the inner core, e.g. the ... before any of the stream data is read. ...
    (comp.lang.java.programmer)