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. Failing Contructor

Failing Contructor

Scheduled Pinned Locked Moved C / C++ / MFC
helptutorialquestion
7 Posts 6 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.
  • D Offline
    D Offline
    Dave Cross
    wrote on last edited by
    #1

    Got a complex class which depends on data files opened in the constructor. Does anyone have any neat ideas about how to handle error conditions? If the files don't exist I don't want the object to be created but I can't see how to do it. TIA Dave Cross

    M S S P 4 Replies Last reply
    0
    • D Dave Cross

      Got a complex class which depends on data files opened in the constructor. Does anyone have any neat ideas about how to handle error conditions? If the files don't exist I don't want the object to be created but I can't see how to do it. TIA Dave Cross

      M Offline
      M Offline
      Michael P Butler
      wrote on last edited by
      #2

      I don't have any neat ideas, I just want to point out that the constructor is not the best place for doing a large amount of work that might fail. Michael :-)

      1 Reply Last reply
      0
      • D Dave Cross

        Got a complex class which depends on data files opened in the constructor. Does anyone have any neat ideas about how to handle error conditions? If the files don't exist I don't want the object to be created but I can't see how to do it. TIA Dave Cross

        S Offline
        S Offline
        Steen Krogsgaard
        wrote on last edited by
        #3

        Exceptions. Just throw an exception when your constructor fails and catch it in the code contructing the object. I think that is actually the *only* right way to do it. Cheers Steen. "To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"

        1 Reply Last reply
        0
        • D Dave Cross

          Got a complex class which depends on data files opened in the constructor. Does anyone have any neat ideas about how to handle error conditions? If the files don't exist I don't want the object to be created but I can't see how to do it. TIA Dave Cross

          S Offline
          S Offline
          Stan Shannon
          wrote on last edited by
          #4

          Doing a lot of work in the constructor is generally considered bad OOP, but if you must do it than exception handling is the best technique to deal with errors, at least if this is going to be a widely distributed class. "But, daddy, that was back in the hippie ages..." My twelve year old son - winning the argument. "Stan, you are an intelligent guy who responds in meaningful ways" Paul Watson 16/10/01

          J 1 Reply Last reply
          0
          • S Stan Shannon

            Doing a lot of work in the constructor is generally considered bad OOP, but if you must do it than exception handling is the best technique to deal with errors, at least if this is going to be a widely distributed class. "But, daddy, that was back in the hippie ages..." My twelve year old son - winning the argument. "Stan, you are an intelligent guy who responds in meaningful ways" Paul Watson 16/10/01

            J Offline
            J Offline
            Joaquin M Lopez Munoz
            wrote on last edited by
            #5

            IMHO doing a lot of work in ctors can't be (in general) consider bad OOP. A design approach that works nicely with OOP and ctors is the idea of having the objects keep an invariant condition that holds for the entire lifespan of the object. This invariants help deal with the object and ease the implementation of their methods --you can think of invariants as a semantic contract with a class instance. So, if initializing an invariant condition takes a lot of work due to the complexity of the invariant, the proper place to do that is precisely the ctor. After construction you know everything's in place, without resorting to init() methods and stuff like that. If you cannot grant that invariant on construction time, throwing is the exact thing to do. I would even dare to say that huge ctors (if properly backed up by meaningful semantics) provide for richer, easier to use classes. Joaquín M López Muñoz Télefónica, Investigación y Desarrollo

            S 1 Reply Last reply
            0
            • D Dave Cross

              Got a complex class which depends on data files opened in the constructor. Does anyone have any neat ideas about how to handle error conditions? If the files don't exist I don't want the object to be created but I can't see how to do it. TIA Dave Cross

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

              Effectively throwing an exception is the way to let the client knows about the error. If lot of stuff is done in the constructor, you probably also want to do some cleanup if an error occurs and in that case one of the following design may help (choose the one that best fit). 1) Uses ressource wrapper classes for ressources (like std::auto_ptr for pointers). Thus every member that allocate a ressource (memory, handle) is a wrapper. 2) Uses the pimpl idiom. The implementation class should then have a trivial constructor that may not have an error (set pointer to NULL, handle to INVALID_HANDLE_VALUE,...) and an initialisation function that do the actual initialisation. class VClass { private: class VImpl; VImpl *m_pImpl; }; class VClass::VImpl { public: VImpl(); // Simple initialisation only ~VImpl(); // Release every allocated ressource void init(); // Complex initialisation }; VClass::VClass() { std::auto_ptr pImpl = new VImpl; pImpl->init(); m_pImpl = pImpl.release(); } VClass::~VClass() { delete m_pImpl; } 3) Derive from a class that hold the ressource and do the initialisation in the derived class constructor by calling an initialisation function in the inherited class. That way if an exception is thrown from the derived class, the base class that hold the ressource will have its destructor called since it is a completly constructed object. 4) Uses wrapper class in the constructor body and at the end of the constructor body transfer the ownership from the wrapper class to the associate member of the class. I do not like complex constructor without using one (or more) of the design above since it complexify the constructor error handling a lot (for ex. closing file that have been opened up to that point). Note that the patterns #2 and #4 above typically allows to reduce compilation depedencies in the header file... which is often desirable when a class is complex. Philippe Mori

              1 Reply Last reply
              0
              • J Joaquin M Lopez Munoz

                IMHO doing a lot of work in ctors can't be (in general) consider bad OOP. A design approach that works nicely with OOP and ctors is the idea of having the objects keep an invariant condition that holds for the entire lifespan of the object. This invariants help deal with the object and ease the implementation of their methods --you can think of invariants as a semantic contract with a class instance. So, if initializing an invariant condition takes a lot of work due to the complexity of the invariant, the proper place to do that is precisely the ctor. After construction you know everything's in place, without resorting to init() methods and stuff like that. If you cannot grant that invariant on construction time, throwing is the exact thing to do. I would even dare to say that huge ctors (if properly backed up by meaningful semantics) provide for richer, easier to use classes. Joaquín M López Muñoz Télefónica, Investigación y Desarrollo

                S Offline
                S Offline
                Stan Shannon
                wrote on last edited by
                #7

                I'm not religious about it one way or the other. I certainly understand that one methodology will never solve every possible design problem. My personal philosophy though remains that a complex ctor made dependent upon exception handling is generally not superior to a simple "init()" call. But I am not prepared to say that it is always inferior. I have always found it very convenient to be able to return a complex object to its original default state at any point in its lifetime with an initialization function of some kind. You just have to remember that the init() cannot be virtual if you intend to use it from the ctor. "But, daddy, that was back in the hippie ages..." My twelve year old son - winning the argument. "Stan, you are an intelligent guy who responds in meaningful ways" Paul Watson 16/10/01

                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