Thread: Constructor failed: design question

  1. #1
    Registered User
    Join Date
    Jun 2003
    Posts
    41

    Constructor failed: design question

    Hi all,
    I am wondering what the best way to tell the user a constructor failed is. What I currently do is have my constructors do very little or nothing, and define an Init() method. This Init() method returns values so it can be checked whether it worked or not, and does everything I'd LIKE to do in my constructor.

    I could also have a bit set to PASS/FAIL or something, and the caller should always check this bit after instantiating an object of one of my classes.

    However neither of these methods seems particularly nice for the calling function, since they could forget to check a bit, or never call Init() before some other method (I can handle this easily internally to my class, however).

    I am wondering what others recommend?? Is there a nice way to tell the calling function "construction failed"?

    Just curious. Thank!

  2. #2
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    If the object cannot be created, then throw an exception from the constructor. This will prevent the object from actually being created. Then, you just do error handling in the catch() statement.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  3. #3
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    >>> my constructors do very little or nothing, and define an Init() method.

    Even with exception handling, there are many that would advocate that approach anyway.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Perhaps I'm missing something here but if a constructor fails it will usually be because of some type of memory issue. The object creation is handled by the compiler and simply reduces down to a simple memory allocation for space in which to store the object (basically).

    So, in essence, you will know if the object failed by testing the pointer. There is no need to put this checking in every one of your classes. It is up to the programmer who creates the object to ensure that the pointer is valid before they use it.

    For instance in DirectX when you create an interface(get a pointer to an interface) you should always check to see if it is valid using the FAILED() macro.

    You can do the same type of thing:
    Code:
    char *test=new char[4000];
    
    if (test) 
    {
      ...allocation succeeded - pointer is valid
    } else ...allocation failed - pointer is not valid
    Code:
    
    //Placed into a header file
    class Example
    {
       int SomeValue1;
       int SomeValue2;
       public:
          Example(void) {SomeValue1=0;SomeValue2=0;};
    };
    
    
    //Placed into a code module - separate from the header
    Example *ThisExample=new Example();
    if (ThisExample)   
    {
       ...object was created/allocated - pointer is valid
       ...SomeValue1 is now 0 as well as SomeValue2
    } 
    else
    { 
    ...object was not created - pointer is not valid
    ...SomeValue1 is invalid as well as SomeValue2
    }
    So it is not up to the class creator/designer to check to see if the object is created or not - it is the responsibility of the programmer who instantiates the class. As far as I'm concerned it is a bad practice to put error checking like this in the class definition since it really has nothing to do with the definition of the class. It has to do with the instantiation of the class.

    As well it is also not the responsibility of the class or class designer to make sure that an object has been destroyed, freed, or deallocated.

    Remember that when you create a class it is not an object yet. It is not an object until you instantiate the class which is going to be done from outside the class by whoever needs to use the class. So to check whether a class is a valid object or not a valid object from inside the class definition, which is not an object yet, is really useless which is probably why destructors and constructors do not and cannot have a return type.

    You might want to read up on C++ and how classes are instantiated to understand more. Perhaps you need to rethink what you are trying to do.


    Hope this helps.




  5. #5
    Registered User
    Join Date
    Jan 2003
    Posts
    648
    Question:

    Say you dynamically create a class using new and the constructor throws an exception. You catch the exception but what happens to the pointer to the class you created? Was it deleted? or do I have to delete it myself?

  6. #6
    Registered User
    Join Date
    Jun 2003
    Posts
    41
    Thanks for the great feedback. In some classes I try to open a file, for example, and if the file simply doesn't exist, then the object really shouldn't be used. Or someone instantiates the object with a bad value (like outside of a range) and the constructor can tell this. Right now I tend to do these things with an explicit method call, like Init(), which they can check the return value against, however throwing an exception sounds like a good idea.

    If the calling function makes a pointer to an object of class A, than just having them check the pointer value would work, but what if someone doesn't want a pointer and wants to allocate it statically? That is:
    Example thisExample(badValue);
    rather than
    Example *thatExample = new Example(badValue);
    In this case there's no pointer to check, however I could be missing something (not the first or last time!).

  7. #7
    Registered User
    Join Date
    May 2003
    Posts
    148
    Originally posted by Speedy5
    Question:

    Say you dynamically create a class using new and the constructor throws an exception. You catch the exception but what happens to the pointer to the class you created? Was it deleted? or do I have to delete it myself?
    [expr.new] 5.3.4 New
    17 If any part of the object initialization described above 67)
    terminates by throwing an exception and the new_expression
    does not contain a new_placement, then the deallocation function
    (3.7.3.2, 12.5) is called to free the memory in which the object
    was being constructed, after which the exception continues to
    propagate in the context of the new_expression

  8. #8
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Originally posted by registering
    Thanks for the great feedback. In some classes I try to open a file, for example, and if the file simply doesn't exist, then the object really shouldn't be used. Or someone instantiates the object with a bad value (like outside of a range) and the constructor can tell this. Right now I tend to do these things with an explicit method call, like Init(), which they can check the return value against, however throwing an exception sounds like a good idea.

    If the calling function makes a pointer to an object of class A, than just having them check the pointer value would work, but what if someone doesn't want a pointer and wants to allocate it statically? That is:
    Example thisExample(badValue);
    rather than
    Example *thatExample = new Example(badValue);
    In this case there's no pointer to check, however I could be missing something (not the first or last time!).
    If you allocate the memory with new, then you can create the pointer without instantiating anything, so you can place the pointer declaration outside the try block, so it'll have scope of the entire function (or block, as the case may be). If you create it statically, then it must be in the scope of the try block, since you can't avoid instantiating it.

    An example:

    Code:
    void f()
    {
       MyClass* obj = 0;
       try
       {
          obj = new MyClass;
       }
       catch(...)
       {
          // Error handling.
          return; // Cannot continue with function.
       }
       obj->func(); // Using obj outside of try block if all went well.
    }
    
    void g()
    {
       try
       {
          MyClass obj;
          obj.func();
       }
       catch(...)
       {
          // Error handling.
       }
    }
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  9. #9
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Originally posted by adrianxw
    >>> my constructors do very little or nothing, and define an Init() method.

    Even with exception handling, there are many that would advocate that approach anyway.
    The benefit of exceptions is this: If the initialization fails (for whatever reason), then if the user does not check the return value of Init(), then they are left with an object in an illegal state. With exceptions, however, you are not left with a potentially hazardous object.

    Also, another way to do this came to mind. A static builder function, and private constructors. Essentially, the static builder function would either do some checking before constructing the object (not always possible), or catch the exception for you. It would then return a pointer to either a newly created object, or a null pointer if it failed to do so.

    It is still good to use the exception method with that, but it gets the try/catch blocks out of the users code, and replaces them with a check for a null pointer (which sometimes isn't quite as imposing).
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  10. #10
    Registered User
    Join Date
    Jun 2003
    Posts
    41

    Thumbs up

    Thanks! I appreciate the feedback.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Game design question
    By h3ro in forum Game Programming
    Replies: 6
    Last Post: 02-28-2008, 08:20 AM
  2. Question about engine design.
    By Shamino in forum Game Programming
    Replies: 9
    Last Post: 01-29-2008, 10:53 AM
  3. question about class design and overloading
    By l2u in forum C++ Programming
    Replies: 7
    Last Post: 12-13-2007, 02:02 PM
  4. database app design question
    By MPSoutine in forum Windows Programming
    Replies: 4
    Last Post: 12-02-2003, 10:13 PM
  5. design question: opinion
    By ggs in forum C Programming
    Replies: 2
    Last Post: 01-29-2003, 11:59 AM