Tom*_*zyk 41 c++ function argument-passing
我有一个看起来像这样的函数:
bool generate_script (bool net, bool tv, bool phone,
std::string clientsID,
std::string password,
int index, std::string number,
std::string Iport, std::string sernoID,
std::string VoiP_number, std::string VoiP_pass,
std::string target, int slot, int port,
int onu, int extra, std::string IP, std::string MAC);
Run Code Online (Sandbox Code Playgroud)
在我看来,它看起来很难看.处理这个问题的正确方法是什么?我应该创建几个具有不同数据类型(int,string和bool)的向量,并将它们作为参数传递给此函数吗?
Que*_*tin 78
如果所有这些参数都有意义相关,请将它们打包在一个结构中.
Ral*_*zky 44
struct
创建一个结构
struct GenerateScriptParams { /* ... */ };
Run Code Online (Sandbox Code Playgroud)
并将所有参数放在那里.实际上,您可以struct
通过实现默认构造函数来提供初始化的默认值,或者在C++ 11中,通过提供单个成员的默认初始化来提供默认值.然后,您可以更改不应默认的值.对于在C++中具有大量参数的函数调用,不能选择性地选择非默认参数.
然而,使用有点难看,因为你必须创建一个临时名称对象,然后更改不应该是默认值的值,然后将对象传递给函数:
GenerateScriptParams gsp;
gsp.net = true;
gsp.phone = false;
gps.extra = 10;
generate_script( gsp );
Run Code Online (Sandbox Code Playgroud)
如果你在几个不同的地方调用该函数,通过提供可链接的变异成员函数来避免这种丑陋是有意义的:
GenerateScriptParams & GenerateScriptParams::setNet ( bool val );
GenerateScriptParams & GenerateScriptParams::setTV ( bool val );
GenerateScriptParams & GenerateScriptParams::setPhone( bool val );
// ... //
Run Code Online (Sandbox Code Playgroud)
然后调用代码可以写
generate_script( GenerateScriptParams()
.setNet(true),
.setPhone(false),
.setExtra(10) );
Run Code Online (Sandbox Code Playgroud)
没有上述丑陋.这避免了仅使用一次的命名对象.
Ale*_*zzi 20
我个人不相信在一个结构中移动所有参数会使代码更好.你只需在地毯下移动污垢.当您要处理结构的创建时,您会遇到同样的问题.
问题是这个结构有多少可重用?如果最终为一个函数调用了18个参数,那么它在您的设计中就不太对了.在进一步分析之后,您可能会发现这些参数可以分组在几个不同的类中,并且这些类可以聚合到一个单独的对象,该对象将是您的函数的输入.您可能还希望更喜欢类来构造以保护您的数据.
编辑
我将举一个小例子来描述为什么有几个类比一个单片结构更好.让我们开始计算您需要编写的测试以涵盖上述功能.输入有18个参数(3个布尔值).所以我们只需要至少15次测试来验证输入(假设值没有互连).
如果没有实施,测试的总数就无法计算,但我们可以了解其大小.让下限所有输入都可以视为布尔值,可能的组合数是2 ^ 18所以262000左右的测试.
现在,如果我们将输入分成几个对象会发生什么?
首先,验证输入的代码从函数移动到每个对象的主体(并且可以重用).
但更重要的是,测试的数量将会崩溃,比如四个一组(每个对象4,4,4和4个参数),测试总数仅为:
2 ^ 4 + 2 ^ 4 + 2 ^ 4 + 2 ^ 4 + 2 ^ 4 = 80
第五个属性是由于对象自身的排列.
那么,更具成本要求的是什么?写几千个测试或几个类?
显然,这是一个粗略的简化,但它将成为问题核心的基础.杂乱的界面不仅仅是风格问题,也不仅仅是开发人员的不方便,也是制作高质量代码的真正障碍.
这是我作为一名专业开发人员在职业生涯中学到的最重要的一课:"大班和胖接口都是邪恶的".这只是我对单一责任原则的启发式版本(我注意到SRP可能很难做到正确,单一责任似乎是合理的,经过一小时编码后它可能不太相同,所以我使用了一些启发式算法规则,以帮助我恢复我的初步选择).
Pov*_*asB 13
或者您可以使用流畅的界面.它看起来像这样:
script my_script(mandatory, parameters);
my_script.net(true).tv(false).phone(true);
Run Code Online (Sandbox Code Playgroud)
如果您具有指定参数的默认值,或者允许其具有部分构造的脚本,则此选项适用.
忽略以某种方式更改功能或程序以减少参数数量的可能性或可取性......
我已经看到了编码标准,它指定了参数列表的格式化时间,以及无法进行重构的情况.一个这样的例子是每行使用双缩进和一个参数(不适用于所有函数 - 仅适用于具有多行参数的函数).
例如
bool generate_script (
bool net,
bool tv,
bool phone,
std::string clientsID,
std::string password,
int index,
std::string number,
std::string Iport,
std::string sernoID,
std::string VoiP_number,
std::string VoiP_pass,
std::string target,
int slot,
int port,
int onu,
int extra,
std::string IP,
std::string MAC);
Run Code Online (Sandbox Code Playgroud)
这里的要点是创建一致的布局并查找具有大量参数的所有函数.
归档时间: |
|
查看次数: |
15031 次 |
最近记录: |