构造函数constructor和类型转换
1. 构造函数调用的时候只带一个参数时(参数列表为一个参数或者多个参数带有默认参数),才可以执行自动转换。即该构造函数的参数类型可以自动转换成该类类型。
Object(const char *name=NULL, int otype=0); // char * 可以自动转换成 Object类型
Object(int param); // int 可以自动转换成Object.
2. 构造函数只允许一次自动转换,不允许连续两次或者多次自动转换, 如例1。
3. explicit 修饰的构造函数(仅限调用时只带一个参数的构造函数才有意义),不允许程序调用该构造函数执行自动类型转换。如例1和例2的对比。
4. explicit 修饰的构造函数,仅允许Direct initialization(相当于explicit 调用constructor),不允许copy initialization(相当于implicit 调用constructor)。如例2.
5. explicit 关键词只是在类内构造函数声明前出现,在类外构造函数的定义处不需添加。
class abc
{
public:
explict abc(int a);
}
abc::abc(int a)
{
....
}
例子1:普通constructor
class
Foo
{
public
:
Foo(const std::
string
&str):
m_string
(str){}
void
output(
void
)
{
std::cout <<
"This is an example! Size is "
<<
m_string
<< std::endl ;
}
private
:
std::
string
m_string
;
};
void
Func(
Foo
a)
{
a.output();
}
int
main()
{
//error: "abcdef"->string->Foo 只允许一次用户类型的自动转换
Func(
"abcdef"
);
//ok! 先强制转换(explicit conversion)为string类型, 再自动转换(implict conversion)为Foo.
Func(std::
string
(
" abcdef"
));
//ok, 先自动转换为string类型,再强制转换为Foo类型.
Func(
Foo
(
" abcdef"
));
//ok ,先自动转换成string类型,再Direct initialization(相当于强制转换 explicit conversion).
Foo
foo(
" abcdef"
);
//ok,先自动转换成string类型,再copy initialization(相当于自动转换 implicit conversion).
Foo
foo =
" abcdef"
;
}
|
例子2:explicit constructor
class
Foo
{
public
:
explicit
Foo(
const
std::
string
& str):
m_string
(str){}
void
output(
void
)
{
std::cout <<
"This is an example! Size is "
<<
m_string
<< std::endl ;
}
private
:
std::
string
m_string
;
};
void
Func(
Foo
a)
{
a.output();
}
int
main()
{
//error
! 先强制转换为string类型, 无法implicit调用构造函数转化为Foo.
Func(std::
string
(
" abcdef"
));
//ok, 先自动转换为string类型,再强制转换(explict)为Foo类型.
Func(
Foo
(
" abcdef"
));
//ok, 先自动转换为string类型,再强制(explicit)调用构造函数。
Foo
foo(
" abcdef"
);
//error, explict constructor仅用于Direct Initializaton.
Foo
foo =
"abcdef"
;
}
|
参考文献
【1】 C++ primer 5th