C++中有非静态块吗?

如果没有,如何优雅地模仿它?

我想替换像这样的东西:

class C{
    public: void ini(){/* some code */}
};
class D{
    std::vector<C*> regis; //will ini(); later
    public: C field1;
    public: C field2;
    public: C field3;             //whenever I add a new field, I have to ... #1
    public: D(){
        regis.push_back(&field1);
        regis.push_back(&field2);
        regis.push_back(&field3); //#1 ... also add a line here
    }
    public: void ini(){
        for(auto ele:regis){
            ele->ini();
        }
    }
};

和 :-
class D{
    std::vector<C*> regis;
    public: C field1;{regis.push_back(&field1);}//less error-prone (because it is on-site)
    public: C field2;{regis.push_back(&field2);}
    public: C field3;{regis.push_back(&field3);}
    public: D(){    }  //<-- empty
    public: void ini(){
        for(auto ele:regis){
            ele->ini();
        }
    }
};

我在C++中发现了许多与 static-block 相关的问题,但未找到有关非静态块的任何问题。

为了易于回答,这里是a full code

可以使用X-MACRO (wiki link)来完成,但我正在尝试避免这种情况。

编辑

在实际情况下,fieldX可以具有从某个C派生的任何类型。

我认为另一个坏的解决方法:-
class D{
    std::vector<C*> regis;
    char f(C& c){   regis.push_back(&c); return 42;}
    public: C field1; char dummyWaste1=f(field1);
    public: C field2; char dummyWaste2=f(field2);
    public: C field3; char dummyWaste3=f(field3);

Edit2(赏金原因)

skypjack的答案非常有用,但是我很好奇要找到更多的选择。
最终目标是模拟具有更多变化的通用非静态块。
换句话说,如果新的解决方案可以解决这个问题,那就太好了:-
class D{
    int field1=5;
    { do something very custom; /* may access field1 which must = 5 */}
    //^ have to be executed after "field1=5;" but before "field2=7"
    int field2=7;
    int field3=8;
    { do something very custom ; /* e.g. "field1=field2+field3" */}
    //^ have to be executed after "field3=8;"
};

而不浪费每个块1个char(或更多-用于对齐)。

最佳答案



您可以直接初始化regis:

std::vector<C*> regis = { &field1, &field2, &field3 };

也就是说,将您的类(class)定义为:
class D{
public:
    C field1;
    C field2;
    C field3;

    void ini(){
        for(auto ele:regis){
            ele->ini();
        }
    }

private:
    std::vector<C*> regis = { &field1, &field2, &field3 };
};

否则,如果您可以将构造函数添加到C,请还原逻辑并将其自身添加到 vector 中:
#include<vector>

struct C {
    C(std::vector<C*> &vec) {
        vec.push_back(this);
        // ...
    }

    void ini() {}
};

class D{
    std::vector<C*> regis{};

public:
    C field1 = regis;
    C field2 = regis;
    C field3 = regis;

    void ini(){
        for(auto ele:regis){
            ele->ini();
        }
    }
};

int main() { D d{}; d.ini(); }

------编辑------

根据评论中的要求:



这是一种可能的替代方法,不需要您修改C:
#include<vector>

struct C {
    void ini() {}
};

struct Wrapper {
    Wrapper(std::vector<C*> &vec) {
        vec.push_back(*this);
        // ...
    }

    operator C *() { return &c; }

private:
    C c;
};

class D{
    std::vector<C*> regis{};

public:
    Wrapper field1{regis};
    Wrapper field2{regis};
    Wrapper field3{regis};

    void ini(){
        for(auto ele:regis){
            ele->ini();
        }
    }
};

int main() { D d{}; d.ini(); }

关于c++ - C++中的非静态块,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43649375/

10-11 16:04