Thread: Declaring an object in an if block

  1. #1
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229

    Declaring an object in an if block

    Hi, I am trying to initialize an object in an if block and make it accessible to the rest of my program without success. For example:

    I want to use different overloaded constructors of ClassA depending on user input, stored in "input" -
    Code:
    if (input == 1) {
         ClassA my_instance(int a);
    } else {
         ClassA my_instance(string b);
    }
    However, in that case, "my_instance" will not be accessible by the code that follows.
    Is there any way I can declare the variable first, outside of the if block, without actually creating the object, then create the object in the if block?

    Thank you very much for your help

  2. #2
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Use an assignment operator, or use a pointer.

    Code:
    class a { a & operator = ( const a & other ) { /* copy stuff from other to this */ } };
    
    void meth( void )
    {
        a b;
    
        if( cond1 ) b = a( stuff );
        if( cond2 ) b = a( otherstuff );
    }
    
    void method( void )
    {
        a * p = 0;
    
        if( cond1 ) p = new a( blaz );
        if( cond2 ) p = new a( blooz );
    
        // use p, making sure it is non-null
    }

  3. #3
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    Thank you for your help.
    That answered my question.

  4. #4
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    I hope you understand why, though.

    It happens because the if statement introduces a new scope. Any objects declared inside this scope will be destroyed once you reach the closing curly brace.

    Do also note that an if statement without curly braces also introduces a scope which finishes immediately after the expression following the if.

    Code:
    int foo = 7;
    if (foo == 7)
        int bar = 13;
    
    bar = 21; // Error. bar was not declared.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  5. #5
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    Thank you for your information.

    Yes, I understand why... but I just couldn't come up with a way to workaround it.

    =)

  6. #6
    Registered User
    Join Date
    Dec 2006
    Posts
    30
    Quote Originally Posted by Tonto
    Use an assignment operator, or use a pointer.

    Code:
    class a { a & operator = ( const a & other ) { /* copy stuff from other to this */ } };
    
    void meth( void )
    {
        a b;
    
        if( cond1 ) b = a( stuff );
        if( cond2 ) b = a( otherstuff );
    }
    
    void method( void )
    {
        a * p = 0;
    
        if( cond1 ) p = new a( blaz );
        if( cond2 ) p = new a( blooz );
    
        // use p, making sure it is non-null
    }
    The first one has some issues though. b is first constructed using the default constructor, which might have undesirable side-effects. Also won't work if you only have non-default constructors, and adding one might be contrary to design principles of your object. And then it is also wasteful to construct something, not use it, and then construct something else and copy it over the first thing.

    The second one is better (it's basically what Java does), but you have to like pointers and dynamic memory allocation.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The first one has some issues though. b is first constructed using the default constructor, which might have undesirable side-effects. Also won't work if you only have non-default constructors, and adding one might be contrary to design principles of your object. And then it is also wasteful to construct something, not use it, and then construct something else and copy it over the first thing.
    Whether what you have outlined are issues or not depends on the context, so it is not really right to say that it has "some issues". After all, the version you declare as "better" has potential issues too, as you noted concerning "pointers and dynamic memory allocation".
    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

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Some more options:
    1) Use a smart pointer, e.g. a boost::scoped_ptr. That saves you deleting the object manually. Otherwise you use the second way above.
    2) Use a boost::optional. This object acts like a pointer in that it can be NULL, so it has a cheap default constructor. However, when you then construct an object into it (it might even have in-place factory support, not sure) it holds it internally, i.e. you don't need dynamic allocation.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by Tonto
    Code:
    void method( void )
    {
        a * p = 0;
    
        if( cond1 ) p = new a( blaz );
        if( cond2 ) p = new a( blooz );
    
        // use p, making sure it is non-null
    }
    New never returns null. It will throw an exeption if allocation failed. Use new(std::nothrow) if you want new to return null on failure.
    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 Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Yeah, but it's possible that none of the conditions were met, and p would still be null

  11. #11
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Perhalps, but It would then be a better idea to add a default condition that asigned p to an empty object or through an exeption.
    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.

  12. #12
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    hmmm actually, I didn't quite understand the first solution, but I took the pointer and dynamic allocation one (I came from Java , so it's a little more famaliar to me). Thank you all for your information/help.

  13. #13
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    The first just changes the object from it's default state to another by assignment (and you may have to overload the assignment operator to do that, like I suggested in my post). The first however, doesn't ever construct an object until whatever condition causes operator new to be called. This might be appropriate in cases where it would not make sense to create a default object, and which needs parameters. And there is the possibility that none of the conditions would be met that would assign the pointer to an object, you need to check for that null.

    >> (I came from Java , so it's a little more famaliar to me)

    Well, just make sure you know that you have to manage the memory yourself, no garbage collection.

    >> Perhalps, but It would then be a better idea to add a default condition that asigned p to an empty object or through an exeption.

    As I said, there are cases where a default object does not make sense, and you'd have to check if p is null to throw an exception.
    Last edited by Tonto; 12-16-2006 at 03:36 PM.

  14. #14
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    I didn't get the first solution because I have never used operator overloads before.
    I will look for it on google.
    Thank you for you time.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Telling a shared_ptr not to delete object?
    By TriKri in forum C++ Programming
    Replies: 5
    Last Post: 08-16-2008, 04:26 AM
  2. Object destroy itself?
    By cminusminus in forum C++ Programming
    Replies: 28
    Last Post: 03-27-2008, 01:08 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