On using several scoped blocks in a C++ function [

2019-08-29 10:04发布

问题:

I am starting to be more and more attracted to writing long C++ algorithmic functions using successive scoped blocks, as follows:

void my_algorithm(const MyStruct1 &iparam1, MyStruct2 &oparam2)
{
    // First block
    MyStruct3 intermediate_var3;
    {
        double temporary_var;
        // Functional step 1.1
        // Functional step 1.2
        intermediate_var3 = ...
    }
    // Second block
    MyStruct4 intermediate_var4;
    {
        double temporary_var;
        // Functional step 2.1
        // Functional step 2.2
        intermediate_var4 = ...
    }
    // Final block
    {
        int temporary_var;
        oparam2 = ...
    }
}

I am starting to think it is a good way to clarify the function structure and to limit the scope of temporary variables (such as counters i, j, k etc). I saw that such scope blocks make sense in C functions to enable new declarations (see Why enclose blocks of C code in curly braces?).

In the context of C++, is this good or bad practice ?

回答1:

This is a clear sign, that you should extract this separate blocks into separate functions.

MyStruct3 DoSth3(params)
{
    double temporary_var;
    // Functional step 1.1
    // Functional step 1.2
    return ...
}

MyStruct4 DoSth4(params)
{
    double temporary_var;
    // Functional step 2.1
    // Functional step 2.2
    intermediate_var4 = ...
}

void my_algorithm(const MyStruct1 &iparam1, MyStruct2 &oparam2)
{
    // First block
    MyStruct3 intermediate_var3 = DoSth3(params);

    // Second block
    MyStruct4 intermediate_var4 = DoSth4(params);

    int temporary_var;
    oparam2 = ...
}

It may happen, that you'll be worried about DoSth3 and DoSth4 being public, as they should be private in the context of my_algorithm. In such case you can solve it in the following way:

class my_algorithm
{
private:
    static MyStruct3 DoSth3(params);
    static MyStruct4 DoSth4(params);

public:
    static void Perform(const MyStruct1 &iparam1, MyStruct2 &oparam2);
};