Ash*_*ppa 32 c++ explicit-constructor
我理解具有一个(非默认)参数的构造函数就像隐式转换器,它从该参数类型转换为类类型.但是,explicit
可用于限定任何构造函数,没有参数的构造函数(默认构造函数)或具有2个或更多(非默认)参数的构造函数.
为什么明确允许这些构造函数?有什么例子可以防止某种隐式转换吗?
Joh*_*itb 37
一个原因当然是因为它没有伤害.
需要的一个原因是,如果您有第一个参数的默认参数.构造函数成为默认构造函数,但仍可用作转换构造函数
struct A {
explicit A(int = 0); // added it to a default constructor
};
Run Code Online (Sandbox Code Playgroud)
C++ 0x实际上将它用于多参数构造函数.在C++ 0x中,初始化列表可用于初始化类对象.理念是
如果使用= { ... }
,则初始化对象与一种"化合物值"在概念上表示对象的抽象值,并且要已经转换到的类型.
如果使用{ ... }
初始值设定项,则直接调用对象的构造函数,而不一定要指定转换.
考虑这个例子
struct String {
// this is a non-converting constructor
explicit String(int initialLength, int capacity);
};
struct Address {
// converting constructor
Address(string name, string street, string city);
};
String s = { 10, 15 }; // error!
String s1{10, 15}; // fine
Address a = { "litb", "nerdsway", "frankfurt" }; // fine
Run Code Online (Sandbox Code Playgroud)
通过这种方式,C++ 0x显示C++ 03的决定,允许在其他构造函数上显式,根本不是一个坏主意.
也许是为了支持维护.通过explicit
在多参数构造函数上使用,可以避免在向参数添加默认值时无意中引入隐式转换.虽然我不相信; 相反,我认为只是在C++中允许许多事情只是为了不使语言定义比现在更复杂.
也许最臭名昭着的案例是返回对非static
局部变量的引用.它需要额外的复杂规则来排除所有"无意义"的事情,而不会影响其他任何事情.所以它只是被允许,如果你使用那个引用就会产生UB .
或者对于构造函数,只要它们的签名不同,就可以定义任意数量的默认构造函数,但是如果有多个默认构造函数,则默认情况下调用它们是相当困难的.:-)
或许更好的问题是,为什么explicit
转换运算符也不允许?
好吧,它将在C++ 0x中.所以没有充分理由不这样做.不允许explicit
转换运营商的实际原因可能是疏忽,或者explicit
首先要采用的斗争,或委员会时间的简单优先排序,或其他什么.
干杯&hth.,
根据高完整性C++编码标准, 您应该将所有sinlge参数构造函数声明为 显式, 以避免在类型转换中偶然使用.在它是一个多参数构造函数的情况下,假设你有一个接受多个参数的构造函数,每个参数都有一个默认值,在某种默认构造函数和转换构造函数中转换构造函数:
class C {
public:
C( const C& ); // ok copy
constructor C(); // ok default constructor
C( int, int ); // ok more than one non-default argument
explicit C( int ); // prefer
C( double ); // avoid
C( float f, int i=0 ); // avoid, implicit conversion constructor
C( int i=0, float f=0.0 ); // avoid, default constructor, but
// also a conversion constructor
};
void bar( C const & );
void foo()
{
bar( 10 ); // compile error must be 'bar( C( 10 ) )'
bar( 0.0 ); // implicit conversion to C
}
Run Code Online (Sandbox Code Playgroud)