Newbie: Cancelling the creation of a class object - c++

This is a discussion on Newbie: Cancelling the creation of a class object - c++ ; Is it possible to cancel or prevent the creation of a class object? I have a fileClass which has a default and non-default constructor (fileName provided as argument). If no fileName is provided or the provided fileName does not exist ...

+ Reply to Thread
Results 1 to 5 of 5

Newbie: Cancelling the creation of a class object

  1. Default Newbie: Cancelling the creation of a class object

    Is it possible to cancel or prevent the creation of a class object?

    I have a fileClass which has a default and non-default constructor
    (fileName provided as argument). If no fileName is provided or the
    provided fileName does not exist or cannot be opened for reading, I
    would like to cancel the creation of the class object.

    Is this possible, if so, how?

    (I would prefer, if possible to do the test at the class level, rather
    than test for a fileName in the program proper and only if successful
    create the object.)


    class fileStream
    {
    public:

    //default constructor
    fileStream();

    //constructor with filename
    fileStream(const string &fileName);

    //destructor
    ~fileStream() {if (inFile.is_open()) inFile.close( );}

    private:

    //the input file stream for reading from the file
    ifstream inFile;
    };


    //--------------------------------------------------------
    //default constructor
    //--------------------------------------------------------
    fileStream::fileStream()
    {
    //how do I cancel the construction of an object?
    }

    //--------------------------------------------------------
    //non-default constructor, fileName provided
    //--------------------------------------------------------
    fileStream::fileStream(const string &fileName)
    {
    if (fileName!="")
    {
    try
    {
    //attempt to open the file
    inFile.open(fileName.c_str());
    }
    catch (...)
    {
    //how do I cancel the construction of an object?

    //if the file cannot be opened or not found
    cout << "\aERROR : \"" << fileName << "\" cannot be found or opened."
    << endl;
    }
    }
    }

  2. Default Re: Newbie: Cancelling the creation of a class object

    * TreatmentPlant:
    > Is it possible to cancel or prevent the creation of a class object?


    Yes, by throwing an exception.


    > I have a fileClass which has a default and non-default constructor
    > (fileName provided as argument). If no fileName is provided or the
    > provided fileName does not exist or cannot be opened for reading, I
    > would like to cancel the creation of the class object.
    >
    > Is this possible, if so, how?


    Yes (see above), but do note that /unless you use advanced techniques/
    you will not thereby simplify the class' other code, which must still
    check for failure at every point, because file operations may fail at
    any time -- e.g., the file may reside on removable storage...

    Objects that represent files therefore usuallt have a nullstate or error
    states.

    E.g., std::ifstream -- although that's not a very design overall, it's
    use of a logical error state (nothing happens in that state) is typical.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?

  3. Default Re: Newbie: Cancelling the creation of a class object

    TreatmentPlant wrote:

    > Is it possible to cancel or prevent the creation of a class object?
    >
    > I have a fileClass which has a default and non-default constructor
    > (fileName provided as argument). If no fileName is provided or the
    > provided fileName does not exist or cannot be opened for reading, I
    > would like to cancel the creation of the class object.
    >
    > Is this possible, if so, how?


    Yes, it is possible.
    If you want to require a fileName to be passed to the constructor, you
    should not provide a default constructor. This way, the compiler will
    barf if someone tries to create an object without passing a fileName.

    If the constructor then finds out that the file can not be opened, you
    throw an exception to abort the construction of the object.

    >
    > (I would prefer, if possible to do the test at the class level, rather
    > than test for a fileName in the program proper and only if successful
    > create the object.)
    >
    >
    > class fileStream
    > {
    > public:
    >
    > //default constructor
    > fileStream();

    Leave this one out.

    >
    > //constructor with filename
    > fileStream(const string &fileName);
    >
    > //destructor
    > ~fileStream() {if (inFile.is_open()) inFile.close( );}
    >
    > private:
    >
    > //the input file stream for reading from the file
    > ifstream inFile;
    > };
    >
    >
    > //--------------------------------------------------------
    > //default constructor
    > //--------------------------------------------------------
    > fileStream::fileStream()
    > {
    > //how do I cancel the construction of an object?


    It is better to avoid getting here in the first place.
    If you provide at least one constructor yourself (like the one below),
    then the compiler will not automagically generate a default
    constructor. This forces all client code to use the constructor that
    takes a fileName argument.

    > }
    >
    > //--------------------------------------------------------
    > //non-default constructor, fileName provided
    > //--------------------------------------------------------
    > fileStream::fileStream(const string &fileName)
    > {
    > if (fileName!="")
    > {
    > try
    > {
    > //attempt to open the file
    > inFile.open(fileName.c_str());


    Unless you tell the inFile object explicitly to do so, this will not
    throw an exception if opening the file fails.
    The reason for this is that failure to open a file is usually no
    exceptional behaviour. And even if opening succeeded, there may be
    external conditions that render the file unreadable (think: removing
    the disk from the system for example).

    To abort the construction, throw an exception:
    if (! inFile.is_open() )
    {
    istringstream iss;
    iss << "\aERROR : \"" << fileName << "\" cannot be found or opened."
    throw std::ios::failure(iss.str());
    }

    > }
    > catch (...)
    > {
    > //how do I cancel the construction of an object?
    >
    > //if the file cannot be opened or not found
    > cout << "\aERROR : \"" << fileName << "\" cannot be found or opened."
    > << endl;
    > }
    > }
    > }


    Bart v Ingen Schenau
    --
    a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
    c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/

  4. Default Re: Newbie: Cancelling the creation of a class object

    TreatmentPlant wrote:
    > Is it possible to cancel or prevent the creation of a class object?


    Others already told you how.

    > class fileStream
    > {
    > public:
    >
    > //default constructor
    > fileStream();
    >
    > //constructor with filename
    > fileStream(const string &fileName);
    >
    > //destructor
    > ~fileStream() {if (inFile.is_open()) inFile.close( );}

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    The marked part is redundant, ifstream's dtor will take care of this.

    However, I'd like to add a few things to what was said about these ctors.
    You should declare all three of default ctor, copy ctor assignment
    operator. If you don't, the compiler will generate default
    implementations. In this case, it can't create operator= and the cctor,
    because ifstream is not copyable, but this is a general rule. Also, you
    should make them private, so they are not accidentally invoked. So, your
    class looks like this:

    class file
    {
    // not default-constructible
    file();
    // not copyable
    file( file const&);
    // not assignable
    file& operator=( file const&);
    public:
    // construct with a filename
    explicit file( std::string const& filename);
    ~file();
    };

    Two things here:
    1. Remember that fields in a class are by default private, so only from
    inside the class or friend code you could accidentally compile code that
    uses these forbidden parts.
    2. The 'explicit' should be prefixed to all one-argument ctors that should
    not be invoked implicitly.

    Note that these things run along the guideline to create an error as early
    as possible:
    - Prefer compiler errors to linker errors.
    - Prefer linker errors to runtime errors.
    - Prefer runtime assertions to undefined behaviour.
    The private/unaccessible parts should not be implemented, so even if you
    manage to compile code that uses these, you would at least get a linker
    error.

    Uli

    --
    FAQ: http://ma.rtij.nl/acllc-c++.FAQ.html

  5. Default Re: Newbie: Cancelling the creation of a class object

    "TreatmentPlant" <NoEmailThanks@DieSpammers.com> wrote in message
    news:454424d4$0$18093$5a62ac22@per-qv1-newsreader-01.iinet.net.au...
    > Is it possible to cancel or prevent the creation of a class object?
    >
    > I have a fileClass which has a default and non-default constructor
    > (fileName provided as argument). If no fileName is provided or the
    > provided fileName does not exist or cannot be opened for reading, I would
    > like to cancel the creation of the class object.
    >
    > Is this possible, if so, how?
    >
    > (I would prefer, if possible to do the test at the class level, rather
    > than test for a fileName in the program proper and only if successful
    > create the object.)
    >
    >
    > class fileStream
    > {
    > public:
    >
    > //default constructor
    > fileStream();
    >
    > //constructor with filename
    > fileStream(const string &fileName);
    >
    > //destructor
    > ~fileStream() {if (inFile.is_open()) inFile.close( );}
    >
    > private:
    >
    > //the input file stream for reading from the file
    > ifstream inFile;
    > };
    >
    >
    > //--------------------------------------------------------
    > //default constructor
    > //--------------------------------------------------------
    > fileStream::fileStream()
    > {
    > //how do I cancel the construction of an object?
    > }
    >
    > //--------------------------------------------------------
    > //non-default constructor, fileName provided
    > //--------------------------------------------------------
    > fileStream::fileStream(const string &fileName)
    > {
    > if (fileName!="")
    > {
    > try
    > {
    > //attempt to open the file
    > inFile.open(fileName.c_str());
    > }
    > catch (...)
    > {
    > //how do I cancel the construction of an object?
    >
    > //if the file cannot be opened or not found
    > cout << "\aERROR : \"" << fileName << "\" cannot be found or opened." <<
    > endl;
    > }
    > }
    > }


    In addition to the others suggestions of throwing and exception, consider
    using a factory to create the object. The factory can create the object,
    then test it somehow (perhaps call object.is_good()) and if it's good return
    a pointer to it, otherwise delete it and return NULL.



+ Reply to Thread

Similar Threads

  1. Replies: 4
    Last Post: 11-13-2007, 11:07 AM
  2. Cancelling events on a COM Object
    By Application Development in forum Python
    Replies: 4
    Last Post: 08-18-2007, 12:05 PM
  3. Replies: 0
    Last Post: 06-05-2007, 03:38 AM
  4. Object creation from a .Net class from VBA
    By Application Development in forum DOTNET
    Replies: 1
    Last Post: 03-13-2006, 06:24 AM
  5. Replies: 1
    Last Post: 02-16-2005, 08:43 AM