Expand scope of a variable initialized in a if/els

2020-02-02 01:45发布

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 statements to construct the object, but the instance is then 'trapped' in the brackets and can't be used further in the code.

Here is what it looks like in code:

if (my_boolean){
    MyClass my_object(arg1); //calling a first constructor
}
else {
    MyClass my_object(arg1,arg2); //calling another constructor
}
//more code using my_object

I tried using the static keyword without success so far. Is there a common way of conditionally using different constructors without having to redefine the constructors?

标签: c++ scope
3条回答
Melony?
2楼-- · 2020-02-02 02:14

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.

查看更多
成全新的幸福
3楼-- · 2020-02-02 02:15

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? :)

查看更多
Rolldiameter
4楼-- · 2020-02-02 02:27

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.

查看更多
登录 后发表回答