Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Constructors throwing exceptions cont.

Constructors throwing exceptions cont.

Scheduled Pinned Locked Moved C / C++ / MFC
question
12 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Tomasz Sowinski

    I'm not sure what you're after now. Can't you just use right constructor with new?

    m_addPrinterDialogPtr = new AddPrinterDialog("doopa", "zoopa", "koopa", NULL, 3.14);

    Tomasz Sowinski -- http://www.shooltz.com

    - It's for protection
    - Protection from what? Zee Germans?

    T Offline
    T Offline
    tom76
    wrote on last edited by
    #3

    I've just found that the following puts the aplication into an assertion loop. // Default constructor AddPrinterDialog::AddPrinterDialog() { try { mAddPrinterDialogPointer = new AddPrinterDialog; } catch(...) { } } All I want is some code that has a constructor throwing an exception if it fails. It seems I can't use the current code. That webpage was interesting, but the code was v.confusing. For example // Example 1(a): Constructor function-try-block // C::C() try : A ( /*...*/ ) // optional initialization list , b_( /*...*/ ) { } catch( ... ) { // We get here if either A::A() or B::B() throws. // If A::A() succeeds and then B::B() throws, the // language guarantees that A::~A() will be called // to destroy the already-created A base subobject // before control reaches this catch block. } is all very well but what if you're NOT inheriting? Or you don't care about parent classes (say you derived from an MFC class). All I want is a default constructor throwing an exception. But I have no idea how you test for an object's existence, especially inside the default constructor's body as the object won't have been created yet. Obseve everything, remember more...

    T 1 Reply Last reply
    0
    • T tom76

      I've just found that the following puts the aplication into an assertion loop. // Default constructor AddPrinterDialog::AddPrinterDialog() { try { mAddPrinterDialogPointer = new AddPrinterDialog; } catch(...) { } } All I want is some code that has a constructor throwing an exception if it fails. It seems I can't use the current code. That webpage was interesting, but the code was v.confusing. For example // Example 1(a): Constructor function-try-block // C::C() try : A ( /*...*/ ) // optional initialization list , b_( /*...*/ ) { } catch( ... ) { // We get here if either A::A() or B::B() throws. // If A::A() succeeds and then B::B() throws, the // language guarantees that A::~A() will be called // to destroy the already-created A base subobject // before control reaches this catch block. } is all very well but what if you're NOT inheriting? Or you don't care about parent classes (say you derived from an MFC class). All I want is a default constructor throwing an exception. But I have no idea how you test for an object's existence, especially inside the default constructor's body as the object won't have been created yet. Obseve everything, remember more...

      T Offline
      T Offline
      Tomasz Sowinski
      wrote on last edited by
      #4

      First of all, you have infinite recursion in your construction - I didn't spot this in original post. Why are you keeping pointer to AddPrinterDlg inside AddPrinterDlg? Second: as the article I've pointed you to said, object doesn't live (and, in fact, have never been born) when exception was thrown during construction. If you expect exceptions coming out of constructor, you should create your object in try/catch block. Tomasz Sowinski -- http://www.shooltz.com

      - It's for protection
      - Protection from what? Zee Germans?

      T 1 Reply Last reply
      0
      • T Tomasz Sowinski

        First of all, you have infinite recursion in your construction - I didn't spot this in original post. Why are you keeping pointer to AddPrinterDlg inside AddPrinterDlg? Second: as the article I've pointed you to said, object doesn't live (and, in fact, have never been born) when exception was thrown during construction. If you expect exceptions coming out of constructor, you should create your object in try/catch block. Tomasz Sowinski -- http://www.shooltz.com

        - It's for protection
        - Protection from what? Zee Germans?

        T Offline
        T Offline
        tom76
        wrote on last edited by
        #5

        Firstly thanks for your continued support. Much appreciated. I am understanding a bit more now. The pointer is a member of AddPrinterDlg. My instructions are that "every constructor that fails shall throw an exception" but I am having problems with this. From what you say, should I assume that every time I create an object in my .cpp files I should put it in a try block? Like so: //... some code... try { if ( !AddPrinterDlg DlgObject ) { throw 100; } } catch( int i ) { cout << "Error: " << i << endl; } DlgObject.DoModal() //... more code... Obseve everything, remember more...

        T P J 3 Replies Last reply
        0
        • T tom76

          Firstly thanks for your continued support. Much appreciated. I am understanding a bit more now. The pointer is a member of AddPrinterDlg. My instructions are that "every constructor that fails shall throw an exception" but I am having problems with this. From what you say, should I assume that every time I create an object in my .cpp files I should put it in a try block? Like so: //... some code... try { if ( !AddPrinterDlg DlgObject ) { throw 100; } } catch( int i ) { cout << "Error: " << i << endl; } DlgObject.DoModal() //... more code... Obseve everything, remember more...

          T Offline
          T Offline
          Tomasz Sowinski
          wrote on last edited by
          #6

          You should use try/catch when your objects may throw an exception from their constructors (and from other methods as well). What kind of failures are you expecting in AddPrinterDlg constructor? Tomasz Sowinski -- http://www.shooltz.com

          - It's for protection
          - Protection from what? Zee Germans?

          T 1 Reply Last reply
          0
          • T Tomasz Sowinski

            You should use try/catch when your objects may throw an exception from their constructors (and from other methods as well). What kind of failures are you expecting in AddPrinterDlg constructor? Tomasz Sowinski -- http://www.shooltz.com

            - It's for protection
            - Protection from what? Zee Germans?

            T Offline
            T Offline
            tom76
            wrote on last edited by
            #7

            I'm not expecting any failures whatsoever, but it's got to be in as a safeguard. So what do I put in the empty constructor body? do I need to put a try and catch block in there or do I just leave it blank? Obseve everything, remember more...

            T 1 Reply Last reply
            0
            • T tom76

              I'm not expecting any failures whatsoever, but it's got to be in as a safeguard. So what do I put in the empty constructor body? do I need to put a try and catch block in there or do I just leave it blank? Obseve everything, remember more...

              T Offline
              T Offline
              Tomasz Sowinski
              wrote on last edited by
              #8

              tom76 wrote: So what do I put in the empty constructor body? Nothing. If your base class constructor throws, you're not going to catch it in constructor body. Standard C++ allows try/catch blocks outside body of the constructor (you could see examples at www.gotw.ca site), but Visual C++ doesn't support that, at least in version 6. Even if you could use try/catch outside of the c'tor body, your only option would be translating caught exception to some other type. For more info on exceptions, I'd recommend reading "Exceptional C++" by Herb Sutter. Tomasz Sowinski -- http://www.shooltz.com

              - It's for protection
              - Protection from what? Zee Germans?

              1 Reply Last reply
              0
              • T tom76

                Firstly thanks for your continued support. Much appreciated. I am understanding a bit more now. The pointer is a member of AddPrinterDlg. My instructions are that "every constructor that fails shall throw an exception" but I am having problems with this. From what you say, should I assume that every time I create an object in my .cpp files I should put it in a try block? Like so: //... some code... try { if ( !AddPrinterDlg DlgObject ) { throw 100; } } catch( int i ) { cout << "Error: " << i << endl; } DlgObject.DoModal() //... more code... Obseve everything, remember more...

                P Offline
                P Offline
                Philippe Mori
                wrote on last edited by
                #9

                As someone else answer, you do not need to detect exception from inside of your constructor as exception will propagate to the caller. And in client code, you should add try/catch only if you want to handle the exception (or do some cleanup before throwing it again). Generally, at some point, you may want to catch the exception and display something to the user and then either continue or quit from there... Also as someone point out, there are good books if you want to learn more. Philippe Mori

                1 Reply Last reply
                0
                • T tom76

                  Firstly thanks for your continued support. Much appreciated. I am understanding a bit more now. The pointer is a member of AddPrinterDlg. My instructions are that "every constructor that fails shall throw an exception" but I am having problems with this. From what you say, should I assume that every time I create an object in my .cpp files I should put it in a try block? Like so: //... some code... try { if ( !AddPrinterDlg DlgObject ) { throw 100; } } catch( int i ) { cout << "Error: " << i << endl; } DlgObject.DoModal() //... more code... Obseve everything, remember more...

                  J Offline
                  J Offline
                  JohnnyG
                  wrote on last edited by
                  #10

                  This is what we do because destructors are not called if an exception occurs in the constructor. We put try/catch blocks in constructors but also do cleanup of allocated memory if it fails. This is a good process for making sure you cleanup what was allocated before the failure occurred. MyObject::MyObject() { // first set all ptrs to null. m_pBlackCat = NULL; m_pWhiteCat = NULL; m_pDog = NULL; // then allocate the memory or whatever process you're going to try to // catch exception on try { m_pBlackCat = new BlackCat(); m_pWhiteCat = new WhiteCat(); m_pDog = new Dog(); } catch(...) // or catch CMemoryException& ce { CleanUp(); throw; } } MyObject::~MyObject() { CleanUp(); } MyObject::CleanUp(); { // It's okay to delete, even if ptr is equal to NULL. delete m_pBlackCat; delete m_pWhiteCat; delete m_Dog; }

                  T 1 Reply Last reply
                  0
                  • J JohnnyG

                    This is what we do because destructors are not called if an exception occurs in the constructor. We put try/catch blocks in constructors but also do cleanup of allocated memory if it fails. This is a good process for making sure you cleanup what was allocated before the failure occurred. MyObject::MyObject() { // first set all ptrs to null. m_pBlackCat = NULL; m_pWhiteCat = NULL; m_pDog = NULL; // then allocate the memory or whatever process you're going to try to // catch exception on try { m_pBlackCat = new BlackCat(); m_pWhiteCat = new WhiteCat(); m_pDog = new Dog(); } catch(...) // or catch CMemoryException& ce { CleanUp(); throw; } } MyObject::~MyObject() { CleanUp(); } MyObject::CleanUp(); { // It's okay to delete, even if ptr is equal to NULL. delete m_pBlackCat; delete m_pWhiteCat; delete m_Dog; }

                    T Offline
                    T Offline
                    tom76
                    wrote on last edited by
                    #11

                    But if I do try { m_pBlackCat = new MyObject; } (which is what I need to do as I am creating an object of type MyObject) I get a recursive loop (the constructor trying to call itself). I cannot use try/catch in the .cpp file as the object goes out of scope like so void DevModeDlg::OnButtonPrinter() { try { AddPrinterDialog Printerbox( this ); } catch( CMemoryException &ce ) { MessageBox( "Error", "Error", MB_OK ); } Printerbox.DoModal(); } Obseve everything, remember more...

                    1 Reply Last reply
                    0
                    • T tom76

                      My current code is this AddPrinterDialog::AddPrinterDialog() { try { mAddPrinterDialogPointer = new AddPrinterDialog; } catch(...) { PostMessage( WM_QUIT, 0, 0 ); } } BUT what happens if I have an overloaded constructor that initialises data members during construction? My try block won't work will it, as I am using 'new' to implicitly call the default constructor. How could I change my code so I can construct an object with all data members initialised to ArgumentA that is passed in? Daniel Obseve everything, remember more...

                      T Offline
                      T Offline
                      tom76
                      wrote on last edited by
                      #12

                      // Default constructor AddPrinterDialog::AddPrinterDialog() { mAddPrinterDialogPointer = NULL; mPointerToParent = NULL; /* If this pointer has failed to be assigned as specified then construction has failed (object cannot, and therefore never has, existed. */ if ( mAddPrinterDialogPointer != NULL ) { throw int(100); } } // The function where we try the constructor code. void DevModeDlg::OnButtonPrinter() { try { DoOnButtonPrinterWork(); // Sneaky! } catch ( int ThrownInt ) { MessageBox ( "Error constructing object Printerbox of class AddPrinterDialog.", "Error", MB_OK ); } } // Call the constructor from here. The object is in scope (if it was // created ok) to be able to call DoModal(). Otherwise it breaks out // and is caught be the catch all block in OnButtonPrinter. void DevModeDlg::DoOnButtonPrinterWork() { AddPrinterDialog Printerbox( this ); Printerbox.DoModal(); } Thank you to all who helped out! Daniel Obseve everything, remember more...

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups