Thread: Declare object without initializing

  1. #1
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300

    Declare object without initializing

    Can I declare an object variable without initializing it? This is mostly a scope problem:

    Code:
    int main () {
           SomeObj eg;  // but this is an initialization ...
           try {
                eg(blah blah);    // so this is pointless
           }
    If I move the declaration into the try block, it is not in main's scope. I know I can do this:
    Code:
    int main () {
           SomeObj *eg;  
           try {
                eg = new SomeObj(blah blah); 
           }
    But now I am using a pointer when I don't need to; also it's my understanding that if you use new, you then need to explicitly use delete.

    Kind of a hassle, is there any way out?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    A declaration of a variable of class type will always initialise the object by invoking a class constructor. If that initialisation fails, an exception will be (or should be) thrown. An exception causes the stack to be unwound - until a scope is reached where, effectively, that object has never existed.

    Code:
    int main()
    {
         SomeObj example;
    
          example.something();   //   this line will not be reached if construction of example fails
    }
    If you're worried about example.something(); being called if construction of example fails, then don't. The standard guarantees it will not happen - assuming the constructor throws an exception if the object cannot be constructed in a valid state.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Code:
    int main () {
           SomeObj* egPtr;.
           try {
               
               SomeObj eg(blah blah);
               egPtr = ⪚
           }
    Can't you do sth like the above? You initialize the object where you want it to be initialized and you use a pointer for it to be in the scope you want it.

    You are not using a pointer when you don't need to. Instead of using eg, you use egPtr. Meaning that outside the try only egPtr is available.

    EDIT: Sorry was in a hurry. The above obviously won't work...
    Last edited by C_ntua; 03-20-2010 at 06:08 PM.

  4. #4
    Registered User
    Join Date
    Mar 2010
    Posts
    15
    An object will always be initialized when you declare it. Why do you want to avoid that? More info please.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I want to avoid it so I can do a try/catch on the initialization, without having to resort to a pointer for a local variable.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Since a variable declared in a scope ceases to exist outside that scope, this can do what you want

    Code:
    int main()
    {
        try
        {
    
             SomeObj eg;
    
              do_something(eg);
        }
        catch (WhateverExceptionThrownIfConstructorFails &)
        {
             // handle a failed construction
        }
        catch (...)
        {
             // handle any other exceptions
        }
    }
    More broadly, good practice with exceptions, usually involves minimising the number of try/catch blocks. Having one for a single operation tends to make the software, as a whole, hard to maintain.
    Last edited by grumpy; 03-20-2010 at 06:24 PM.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    SomeObj *eg;
    Even in this instance I would prefer to initialize the pointer to 0.

  8. #8
    Registered User
    Join Date
    Mar 2010
    Posts
    15
    Quote Originally Posted by MK27 View Post
    I want to avoid it so I can do a try/catch on the initialization, without having to resort to a pointer for a local variable.
    So put the declaration inside the try-catch block. Use grumpy's code.

  9. #9
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by MK27 View Post
    If I move the declaration into the try block, it is not in main's scope. I know I can do this:
    Code:
    int main () {
           SomeObj *eg;  
           try {
                eg = new SomeObj(blah blah); 
           }
    But now I am using a pointer when I don't need to; also it's my understanding that if you use new, you then need to explicitly use delete.
    You do need a pointer here, because if construction fails, you would not have a valid object to work with. So you need a pointer than can be set to null.

    Better to use code like grumpy. Then whatever uses the object will not have to worry about dealing with an invalid object.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  10. #10
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Better to use code like grumpy. Then whatever uses the object will not have to worry about dealing with an invalid object
    This can also be accomplished without the try catch block if you only do operations in a constructor that are guaranteed to never fail. What if if someone wanted to declare a SomeObj instance on the stack in a class?

    Code:
    class Foo
    {
        public:
    
        private:
           SomeObj m_someObj;
    };
    Last edited by VirtualAce; 03-21-2010 at 02:05 AM.

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    That's not what the question was about, Bubba. The question concerned being able to catch exceptions thrown when constructing an object within a try block, but allow that object to be used after the try block. He wanted to be able to do this;
    Code:
    int main()
    {
        try
        {
            SomeObj example;   // and no use of pointers here
        }
        catch (...)
        {
             recover();
        }
    
        // do things with example here
    }
    In other words, he wants an object local to a scope to remain usable after exiting that scope.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  12. #12
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by mustermeister View Post
    So put the declaration inside the try-catch block. Use grumpy's code.
    Okay, well the whole reason I started this thread was because the first (and so far, only) time I tried that I get an error:
    Code:
    int main() {
    	try {
    		OATserver valis(666, 1, "oatsv.log");
    	}
    	catch (int err) {
    		cerr << "OATserver FAIL -> ";
    		switch (err) {
    			case (SOCKERR):
    				perror("Socket: ");
    				break;
    			case (BINDERR):
    				perror("Bind: ");
    				break;
    			case (LISTENERR):
    				perror("Listen: ");
    				break;
    			default:
    				cerr << "??????\n";
    		}
    	}
    
    	struct sockaddr_in in;
    
    	valis.acptlist.push_back("127.0.0.1");
    	valis.waitOnCall(&in);
    
    	return 0;
    }
    server.cpp: In function ‘int main()’:
    server.cpp:92: error: ‘valis’ was not declared in this scope

    Is this some nuance here that will make this work? It seems very silly to me (altho it is normal scoping, wouldn't it be nice if try "returned" it's variables on sucess?), I am glad to hear it is not supposed to be that way.
    Last edited by MK27; 03-21-2010 at 09:07 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    If you read grumpy's example in post #6, you should be able to see that this can work:
    Code:
    int main() {
        try {
            OATserver valis(666, 1, "oatsv.log");
    
            struct sockaddr_in in;
    
            valis.acptlist.push_back("127.0.0.1");
            valis.waitOnCall(&in);
        }
        catch (int err) {
            cerr << "OATserver FAIL -> ";
            switch (err) {
                case (SOCKERR):
                    perror("Socket: ");
                    break;
                case (BINDERR):
                    perror("Bind: ");
                    break;
                case (LISTENERR):
                    perror("Listen: ");
                    break;
                default:
                    cerr << "??????\n";
            }
        }
    
        return 0;
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Bubba View Post
    This can also be accomplished without the try catch block if you only do operations in a constructor that are guaranteed to never fail. What if if someone wanted to declare a SomeObj instance on the stack in a class?
    Good point, and I had been thinking to just use an empty constructor* and then a separate init() function. But I don't think that should be necessary, and the reading I've done explicitly stated that part of the purpose of exceptions was for constructors, since constructors cannot return a value, making normal error checking awkward (tho there are other simple ways around that).

    *It is hard to meaningfully "construct" an inet server object that does not involve some operations that cannot be guaranteed not to fail.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  15. #15
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by laserlight View Post
    If you read grumpy's example in post #6, you should be able to see that this can work:
    Well of course it will So am I suppose to keep all of main inside the try block then?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Initializing constant object member of a class
    By Canadian0469 in forum C++ Programming
    Replies: 3
    Last Post: 12-03-2008, 08:05 PM
  2. Telling a shared_ptr not to delete object?
    By TriKri in forum C++ Programming
    Replies: 5
    Last Post: 08-16-2008, 04:26 AM
  3. ERRPR: Object reference not set to an instance of an object
    By blackhack in forum C++ Programming
    Replies: 1
    Last Post: 07-13-2005, 05:27 PM
  4. Set Classes
    By Nicknameguy in forum C++ Programming
    Replies: 13
    Last Post: 10-31-2002, 02:56 PM
  5. Set Classes
    By Nicknameguy in forum C++ Programming
    Replies: 3
    Last Post: 10-21-2002, 07:40 PM