我知道关键字explicit可用于防止隐式转换.
例如
Foo {
public:
explicit Foo(int i) {}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,在什么条件下,应该禁止隐含转换?为什么隐式转换有害?
Bri*_*ndy 11
使用explicit时,你会喜欢一个编译错误.
explicit 仅当构造函数中有一个参数时才适用(或许多第一个参数只有没有默认值的参数).
你可能希望explicit在程序员错误地构造一个对象的任何时候使用该关键字,认为它可能会做一些它实际上没做的事情.
这是一个例子:
class MyString
{
public:
MyString(int size)
: size(size)
{
}
//... other stuff
int size;
};
Run Code Online (Sandbox Code Playgroud)
使用以下代码,您可以执行此操作:
int age = 29;
//...
//Lots of code
//...
//Pretend at this point the programmer forgot the type of x and thought string
str s = x;
Run Code Online (Sandbox Code Playgroud)
但是调用者可能意味着在MyString变量中存储"3"而不是3.最好得到一个编译错误,这样用户可以先调用itoa或x变量上的其他转换函数.
将为上述代码生成编译错误的新代码:
class MyString
{
public:
explicit MyString(int size)
: size(size)
{
}
//... other stuff
int size;
};
Run Code Online (Sandbox Code Playgroud)
编译错误总是优于错误,因为它们可以立即显示以供您更正.
它引入了意想不到的临时工:
struct Bar
{
Bar(); // default constructor
Bar( int ); // value constructor with implicit conversion
};
void func( const Bar& );
Bar b;
b = 1; // expands to b.operator=( Bar( 1 ));
func( 10 ); // expands to func( Bar( 10 ));
Run Code Online (Sandbox Code Playgroud)
一个现实世界的例子:
class VersionNumber
{
public:
VersionNumber(int major, int minor, int patch = 0, char letter = '\0') : mMajor(major), mMinor(minor), mPatch(patch), mLetter(letter) {}
explicit VersionNumber(uint32 encoded_version) { memcpy(&mLetter, &encoded_version, 4); }
uint32 Encode() const { int ret; memcpy(&ret, &mLetter, 4); return ret; }
protected:
char mLetter;
uint8 mPatch;
uint8 mMinor;
uint8 mMajor;
};
Run Code Online (Sandbox Code Playgroud)
VersionNumber v = 10;几乎可以肯定是一个错误,所以explicit关键字需要程序员输入VersionNumber v(10);- 如果他或她使用一个体面的IDE - 他们会通过它想要的IntelliSense弹出窗口注意到encoded_version.
| 归档时间: |
|
| 查看次数: |
2443 次 |
| 最近记录: |