在类mutator中使用assert()是一种好习惯吗?

时间:2010-06-13 05:30:48

标签: c++ assert

例如:

void Date::month(unsigned int inMonth) {
    assert(inMonth <= 12);
    _month = inMonth;
}

如果这不是一个好的做法,那么正确的方法是什么?

4 个答案:

答案 0 :(得分:4)

您不应使用assert来确保 public 成员函数的参数有效。原因是你的类的客户端无法以任何有意义的方式对失败的断言作出反应(断言从发布版本中删除的事实也无济于事)。

根据经验,断言只应用于严格受您控制的事物(例如,私有方法的参数)。

在这种情况下,你最好抛出std::invalid_argument例外:

void Date::month(unsigned int month) 
{
    if(month == 0 || month > 12)
    {
        throw std::invalid_argument("a month must be in the [1-12] range"); 
    }
    _month = month;
}

答案 1 :(得分:1)

是的。

这是正确的方法。

虽然我称之为setMonth()而不是month()

还要记住assert()在发布版本中没有被预处理。所以如果你想要一些在发布中也能工作的东西,那么要么自己编写断言,要么进行适当的运行时检查。

答案 2 :(得分:1)

另一种为代码提供更多可读性的方法是定义月份的枚举类型:

enum e_Month {
   e_Month_January,
   e_Month_February, 
   e_Month_March, 
   // etc..
   e_Month_December
};

现在你的任务变为:

void Date::month(e_Month inMonth) { _month = inMonth; }

大多数编译器都会因为为枚举指定另一个类型而导致错误,因此编译时安全性始终在范围内。

答案 3 :(得分:0)

没关系,只要在应用程序中出现意外输入,就可以断言。 另外抛出类似ArgumentException的异常,因为你不想设置无效的月份值。