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中发现了与静态块有关的许多问题,但没有发现任何关于非静态块的问题.
为了方便回答,这里是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个字符(或更多 – 用于对齐).
解决方法
how to emulate it elegantly?
您可以直接初始化regis:
std::vector<C*> regis = { &field1,&field2,&field3 };
也就是说,将你的班级定义为:
class D{ public: C field1; C field2; C field3; void ini(){ for(auto ele:regis){ ele->ini(); } } private: std::vector<C*> regis = { &field1,&field3 }; };
否则,如果您可以向C添加构造函数,请恢复逻辑并将其自身添加到向量中:
#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
is a holy class for me. Is it possible to not hackC
?
这是一个可能的选择,不需要你修改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(); }