检查构造函数与设置函数

检查构造函数与设置函数

问题描述:

这是一个非常简单的问题。假设我有一类检查构造函数与设置函数

class A 
{ 
public: 
    A(int); 
    void setA(int); 
private: 
    int a; 
}; 

与实施

A::A(int a_) : a(a_) { } 
void A::setA(int a_) { a = a_; } 

比方说,我想避免a = 0但我不想抛出异常,我只是想保持一个有效的对象与a = 1而不是在那种情况下(为什么现在没有关系)。

然后,我可以在构造函数中添加一个if语句,并在setA中检查参数是否为0,并在该情况下将其设置为1。从概念上讲,这告诉我,在这种情况下,我应该更改构造函数,而不是在那里初始化a,我应该在构造函数中调用setA。通过这种方式,检查代码只写入一次(请记住,这是一个简单的情况,但验证在其他情况下可能会更复杂)。

现在,该方法涉及在构造函数中调用额外的函数。两次编写验证代码效率更高吗?那么如果setA只是偶尔使用呢?

+2

无论如何可能会内联,将其添加到'setA'并在构造函数中调用'setA'。不要担心这些(似乎是但实际上不是)性能差异。写干净的代码。优化器将为您完成剩下的工作。 –

+1

你不需要重命名参数:'A :: A(int a):a(a){}'很好。 – nwp

我同意你的激情来防止代码重复。只是要小心过度,1班轮可能会过度。

如果你打算做检查,虽然你应该使用一个实现文件的功能或privatestatic的方法来做到这一点:

int preventZero(const int a_) { return a_ == 0 ? 1 : a_; } 

然后你就可以在你的实现使用它,如下所示:

A::A(int a_) : a(preventZero(a_)) { } 
void A::setA(int a_) { a = preventZero(a_); } 

在构造函数中使用验证调用setter肯定会更好,因为代码重复是邪恶的。您也可以将其内联以确保您不会浪费CPU周期,但我认为这是过早的优化。

+1

现代编译器不听'inline'。 –

+0

有编译器特定的属性强制内联AFAIK,比如__forceinline for VS – dmsovetov

+0

@GillBates除了使你的代码不可移植之外,'__forceinline'告诉编译器忽略它更好的判断和使用你的代码。请不要使用这种'__forceinline'。 –