使构造函数显式是一个很好的实践

Che*_*eng 8 c++

在设计公共API时,将构造函数设置为显式是一种好的做法吗?

class A {
public:
    //explicit A(int i){}
    A(int i){}
};

void fun(const A& a) {}

int main() {
    // If I use explicit for A constructor, I can prevent this mistake.
    // (Or shall I call it as feature?)
    fun(10);
}
Run Code Online (Sandbox Code Playgroud)

或者我应该允许隐式转换,以允许用户以较少的输入调用我的API?

Bjö*_*lex 9

构造函数应该是显式的,除非隐式转换在语义上有意义(例如,将转换intA?的含义是什么).减少打字不应成为指导该决定的标准.考虑可读性(这是隐式转换的主要参数)以及代码的理解程度.一个不直观的隐式演员会让代码的读者抓住他们的头脑.

PS:我现在似乎无法想出一个很好的例子,所以任何帮助都会受到赞赏.

  • 隐式转换的例子:任何数字(例如bignum库,或日期/时间库) - 反对隐式转换:只考虑可以用初始大小初始化的`std :: vector`类. (7认同)
  • @Tadeusz:即使它有意义,我也会反对它.你忘了一个`#include`,你的代码默默地调用了错误的函数.编写`complex(42.0)`比调试到深夜更容易找到这样的错误. (2认同)

Chu*_*dad 5

就是我在"DanielKrügler"的共鸣中找到的

如果我们从今天开始设计C++,那么很可能默认情况下所有构造函数和转换函数都是"显式的",但用户可以使用"隐式".唉,时间不能回头,我们必须忍受目前的状态.这意味着我们必须小心隐式构造函数(复制/移动构造函数除外).将构造函数显式化是一个更安全的规则,其中涉及某种形式的转换(即任何参数类型U与实际类型T不同的构造函数).

  • DanielKrügler是谁? (2认同)

Ral*_*lph 5

是的,默认情况下,任何可以使用一个参数调用的构造函数都应该是显式的.遵循这条规则将避免微妙的错误,这是很难找到的.

当然,这条规则有例外:

  • 如果您的类具有围绕一个参数类型的包装器的语义,则可能需要隐式转换.

  • 复制构造函数不应该是显式的(否则你会失去传值调用的可能性).