当函数有很多参数和客户端代码只需更改其中时,如何处理情况就可以处理
how to deal with situation when function has lot of params and client code needs only change only few of them?
在这种情况下如何不迷失?例如,这是一个返回bool但接收10个参数的函数:
bool myFunc(bool par1 = true, bool par2 = false, bool par3 = true,
bool par4 = true /* and so on */ ) {}
,假设该函数参数设置为90%的情况。但是有时客户代码只想更改其中的一些。我在这里看到的唯一选择是艰苦地复制所有默认参数,直到我们到达需要更改的访问量为止。以这种方式调用此功能的任何机会:
bool myVal = myFunc(par10 = true, par20 = false);
因此,任何读取代码的人都知道该代码发生了什么(参数的名称很长,但有意义),此外默认参数?
有一个中等著名的习语:命名参数成语。
这个想法很简单:
class Parameters {
public:
Parameters(): _1(true), _2(false), _3(true), _4(true) {}
bool get1() const { return _1; }
bool get2() const { return _2; }
bool get3() const { return _3; }
bool get4() const { return _4; }
Parameters& set1(bool t) { _1 = t; return *this; }
Parameters& set2(bool t) { _2 = t; return *this; }
Parameters& set3(bool t) { _3 = t; return *this; }
Parameters& set4(bool t) { _4 = t; return *this; }
private:
bool _1;
bool _2;
bool _3;
bool _4;
};
bool myFunc(Parameters p);
然后客户可以做:
result = myFunc(Parameters());
或:
result = myFunc(Parameters().set4(false));
请查看boost.parameter库。
使用此库来编写函数和类模板可以 按名称接受参数:
new_window("alert", _width=10, _titlebar=false); smart_ptr<Foo, deleter<Deallocate<Foo> >, copy_policy<DeepCopy> > p(new Foo);
由于可以按任何顺序传递命名的参数,因此当功能或模板具有多个时,它们特别有用 具有有用的默认值的参数。图书馆也支持 推导参数;也就是说,身份的参数可以 从他们的类型中得出。
这是避免这种接口的原因之一。为您的功能创建包装器,接受包含所有参数的结构。在客户端上,实例化默认配置(只要您想调用函数;例如,在对象上下文中)。每当您想调用函数时,请将配置复制到另一个实例,更改所需的值并将其传递给包装的func。
或者,如果可能的话,甚至更好,可以直接更改功能签名,而无需包装器接受汇总配置。
使用可以使用boost::bind
(在C 03)或std::bind
(在C 11上)重新排序并将某些参数修复到您的函数。
如果您有一些参数仅成对有意义,请使用超载函数。
所以,而不是例如(对不起,现在没有更好的例子)
// Adds a new TODO. Either this is a low-prio TODO with no defined
// deadline, xor a deadlined TODO for which year, month, day must
// be passed.
void add_todo (std::string description, int year=-1, int month=-1, int day=-1);
做
void add_todo (std::string description, int year, month, day);
void add_todo (std::string description) {
add_todo(description, -1, -1, -1);
}
因此,要执行两个可能的呼叫签名中的一个。
当然,最好添加更多的结构,例如Date
。但是即使那样,我还是不建议仅仅为此而制作 Date
"无效":
void add_todo (std::string description, Date = Date::None); // <-- I wouldn't
但是
void add_todo (std::string description);
void add_todo (std::string description, Date deadline);
或有时没有超载,根本没有默认值
void add_todo (std::string description);
void add_deadlined_todo (std::string description, Date deadline);
- 警告处理为错误这里有什么问题
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用流处理接收到的数据
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 基于多个条件处理地图中的所有元素
- 如何用数字处理log(0)
- SSL上的`curl_easy_send`和`curl_asy_recv`:如何处理`CURLE_AGAIN`
- 错误处理.将系统错误代码映射到泛型
- 从文本文件中读取时钟时间和事件时间并进行处理
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 用于矢量处理的多个线程
- 处理未处理的异常更改C++
- 使用信号处理程序处理从 FIFO 接收的数据
- 使用QT的C 处理DOM处理后的XML属性顺序
- C++异常处理如何处理异常派生类
- 如何处理信号处理库的输入/输出类型