Expand scope of a variable initialized in a if/else sequence

后端 未结 3 778
轮回少年
轮回少年 2020-12-07 03:22

I\'m writing a piece of code in which I\'d like to use a different constructor of a class depending on a condition. So far I\'ve used if and else s

相关标签:
3条回答
  • 2020-12-07 04:04

    try the following :)

    MyClass my_object = my_boolean ? MyClass(arg1) : MyClass(arg1,arg2);
    

    Take into account that this code will work even if the class has no default constructor.

    Here is a demonstrative example

    #include <iostream> 
    #include <cstdlib>
    #include <ctime>
    
    int main () 
    {
        struct Point
        {
            Point( int x ) : x( x ) {}
            Point( int x, int y ) : x( x ), y( y ) {}
            int x = 0;
            int y = 0;
        };
    
        std::srand( ( unsigned )std::time( 0 ) );
    
        Point p = std::rand() % 2 ? Point( 1 ) : Point( 1, 2 );
    
        std::cout << "p.x = " << p.x << ", p.y = " << p.y << std::endl;  
    
        return 0; 
    }
    

    I have gotten the following output

    p.x = 1, p.y = 2
    

    What output have you gotten? :)

    0 讨论(0)
  • 2020-12-07 04:04

    If you want to use a variable outside of a given scope, it must be declared outside that scope.

    void foo()
    {
        MyClass my_object;
        if (my_boolean){
            my_object = MyClass(arg1); //calling a first constructor,
                                       //then copy or move assignment
        }
        else {
            my_object = MyClass(arg1,arg2); //calling another constructor,
                                       //then copy or move assignment
        }
        //more code using my_object
    }
    //Can no longer access my_object
    

    If you want to do it this way, I suggest defining a move assignment operator if the default will not work for your purposes (or there isn't a default move assignment operator).

    Also, the code where you are using my_object may be cleaner if you move the if/else blocks and object construction to a separate function, then do something like:

    MyClass my_object = make_object(my_boolean);
    

    Or, if arg1 and arg2 aren't global,

    MyClass my_object = make_object(my_boolean, arg1, arg2);
    

    If creating an object gets more complicated than what you've asked about here, you may wish to look into the factory pattern.

    0 讨论(0)
  • 2020-12-07 04:10

    You can use a smart pointer instead of a direct instance:

    std::unique_ptr<MyClass> my_object;
    
    if (my_boolean) {
         //calling a first constructor
        my_object.reset(new MyClass(arg1));
    }
    else {
        //calling another constructor
        my_object.reset(new MyClass(arg1,arg2));
    }
    //more code using my_object
    

    In contrast to some other solutions proposed here, this will also work for bigger if() {} else if() {} sequences, or switch blocks.


    In case you can't use a compiler capable of the latest standard, you can use the good old std::auto_ptr in the exactly same manner.

    "I tried using the static keyword without success so far."

    Good so! A static variable is certainly not what you want here.

    0 讨论(0)
提交回复
热议问题