[英]Passing int as bool argument in C++
could someone explain what happens in this code:有人可以解释这段代码中发生了什么:
example here: https://ideone.com/1cFb4N此处示例: https://ideone.com/1cFb4N
#include <iostream>
using namespace std;
class toto
{
public:
bool b;
toto(bool x)
{
cout<< "constructor bool:" << (x ? "true": "false")<<endl;
b = x;
}
~toto() {}
};
int main()
{
toto t = new toto(0);
cout << "t.b is " << (t.b ? "true": "false")<<endl;
t = new toto(false);
cout << "t.b is " << (t.b ? "true": "false")<<endl;
return 0;
}
output: output:
constructor bool:false
constructor bool:true
t.b is true
constructor bool:false
constructor bool:true
t.b is true
In this declaration在这份声明中
toto t = new toto(0);
the object t
of the class type toto
is initialized by the pointer returned by the expression new toto(0)
. class 类型
toto
的 object t
由表达式new toto(0)
返回的指针初始化。 As the returned pointer is not equal to nullptr
then it is implicitly converted to the boolean value true.由于返回的指针不等于
nullptr
,因此它被隐式转换为 boolean 值 true。
So in fact you have所以事实上你有
toto t = true;
except that there is a memory leak because the address of the allocated object is lost.除了有一个 memory 泄漏,因为分配的 object 的地址丢失了。 So the allocated object can not be deleted.
所以分配的object不能删除。
You could imagine the declaration above the following way.您可以通过以下方式想象上面的声明。
toto *ptr = new toto(0)
toto t = ptr;
So the first line of this output所以这个output的第一行
constructor bool:false
constructor bool:true
corresponds to the dynamically created object with the argument 0对应动态创建的参数为0的object
new toto(0)
Then the returned pointer is used as an initializer and is implicitly converted to the boolean value true
that is used to initialize the declared object t
.然后返回的指针用作初始化器,并隐式转换为 boolean 值
true
,用于初始化声明的 object t
。 So the second line shows the call of the conversion constructor (constructor with a parameter) with the value true.因此,第二行显示了值为 true 的转换构造函数(带参数的构造函数)的调用。
There is no great difference between the above declaration and this assignment statement上面的声明和这个赋值语句没有太大区别
t = new toto(false);
because again a pointer is used in the right hand of the assignment.因为在赋值的右边再次使用了一个指针。
So the implicitly defined copy assignment operator converts the value of the pointer that is not equal to nullptr
to the boolean value true
.因此隐式定义的复制赋值运算符将不等于
nullptr
的指针的值转换为 boolean 值true
。
This assignment you may imagine the following way您可以通过以下方式想象此作业
toto *ptr = new toto(false);
t = toto( ptr );
And again there is a memory leak.再次出现 memory 泄漏。
From the C++ 14 Standard (4.12 Boolean conversions)来自 C++ 14 标准(4.12 Boolean 转换)
1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool.
1 算术纯右值、无作用域枚举、指针或指向成员类型的指针可以转换为 bool 类型的纯右值。 A zero value, null pointer value, or null member pointer value is converted to false;
零值、null 指针值或 null 成员指针值转换为 false; any other value is converted to true.
任何其他值都将转换为 true。 For direct-initialization (8.5), a prvalue of type std::nullptr_t can be converted to a prvalue of type bool;
对于直接初始化 (8.5),std::nullptr_t 类型的纯右值可以转换为 bool 类型的纯右值; the resulting value is false.
结果值为假。
Any integer value is implicitly convertible to bool
, with 0 converting to false
, and all other values converting to true
.任何 integer 值都可以隐式转换为
bool
,其中 0 转换为false
,所有其他值转换为true
。
The same applies to pointers, with null pointers converting to false
, and all others converting to true
.这同样适用于指针,null 个指针转换为
false
,所有其他指针转换为true
。
toto t = new toto(0);
is equivalent to:相当于:
// Create new toto instance, convert 0 to false and assign to p
toto* p = new toto(0);
// Create toto instance on the stack and convert non-null pointer p to true
toto t = toto(p);
You can prevent these surprising conversions by marking single argument constructors as explicit
, meaning they won't be allowed to be considered during implicit conversions:您可以通过将单参数构造函数标记为
explicit
来防止这些令人惊讶的转换,这意味着在隐式转换期间不允许考虑它们:
class toto
{
public:
bool b;
explicit toto(bool x)
{
cout<< "constructor bool:" << (x ? "true": "false")<<endl;
b = x;
}
~toto() {}
};
In this statement:在这个声明中:
toto t = new toto(0);
in the expression new toto(0)
you are allocating a toto
with a default argument 0
.在表达式
new toto(0)
中,您正在分配一个默认参数0
的toto
。 This int
can be implicitly converted to the bool
value false
, and this calls the bool
constructor, resulting in the output:此
int
可以隐式转换为bool
值false
,这会调用bool
构造函数,结果为 output:
constructor bool:false
Then you are doing the assignment:然后你正在做作业:
toto t = /* pointer returned by new */;
This pointer can be implicitly converted to bool
, and since this pointer is not nullptr
, it has a non-zero value.该指针可以隐式转换为
bool
,并且由于该指针不是nullptr
,因此它具有非零值。 This combined with the fact that the toto
constructor accepting a bool
is not explicit
means that the constructor from bool
is called for t
, resulting in:这与接受
bool
的toto
构造函数不是explicit
的事实相结合意味着bool
的构造函数被调用为t
,导致:
constructor bool:true
and this makes the b
member of t
have the value true
, and hence the next line of code results in the output:这使得
t
的b
成员具有值true
,因此下一行代码导致 output:
t.b is true
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.