构造函数中的空字符串被解释为布尔值

4

我正在进行一个QT项目,并发现了奇怪的行为:

我有一个类,其中有几个构造函数看起来像这样:

DB_Variable(QString name, QString newValue):
name(name),value_string(newValue), var_type(DB_STRING){}

DB_Variable(QString name, bool newValue):
    name(name), value_bool(newValue), var_type(DB_BOOL){}

我现在想使用第一个构造函数创建一个对象,如下:

DB_Variable foo("some_name"," ");

我希望空字符串被解释为QString,但调用了第二个(bool)构造函数。有人能告诉我为什么吗?“”是一个指向空字符串的指针,然后变成了bool而不是字符串吗?
Foo

如果您在构造函数中使用 explicit 关键字会发生什么? - shuttle87
1
对于空字符串,您可以使用QString()。但是," "代表一个空格。 - vahancho
1
@shuttle87:会发生完全相同的事情。explicit 防止构造函数用于隐式转换,并且不影响应用于其参数的转换。 - Mike Seymour
@MikeSeymour 感谢,我想我曾经误解了 explicit 的作用,现在我更好地理解它了。 - shuttle87
3个回答

6
这个问题源于构造函数中进行的隐式转换。你代码中的字符串字面值被存储为const char类型。因为你没有采用此类型的构造函数,编译器会尝试在你的构造函数中寻找一种类型转换到它可以找到的类型。
在这种情况下,const char*QString更容易转换为bool,所以当你这样做时:
DB_Variable foo("some_name"," ");

构造函数
DB_Variable(QString name, bool newValue):

被称为。

请注意,你看到的行为不是因为" "与任何其他字符串字面量不同而受到特殊处理,而是因为你很可能没有使用bool,bool类型的构造函数(所有的构造函数都以QString作为第一个参数吗?)。如果你有以下构造函数之一,那么很有可能:

DB_Variable(bool test1, bool newValue):

当您执行类似于DB_Variable foo("some_name"," ");时,应该调用此函数。

如果要获得您想要的结果,可以这样传递QStrings

DB_Variable foo(QString("some_name"), QString());

或者定义一个构造函数,其第二个参数为const char*

1
隐式转换并不发生在构造函数中,而是在调用构造函数之前,以匹配其元素。 - James Kanze
哦,我明白我在这里犯的错误了。我已经相应地编辑了我的帖子。 - shuttle87
好的,这正是我所怀疑的。我现在添加了const char*构造函数,以便调用正确的函数。谢谢! - FooTheBar
@user3442125,很高兴这有所帮助!如果这个或任何答案解决了你的问题,请考虑通过点击复选标记接受它。这向更广泛的社区表明你已经找到了解决方案,并为回答者和你自己赢得了一些声誉。没有义务这样做。 - shuttle87

1
我希望空字符串被解释为QString,但调用了第二个(bool)构造函数。有人能告诉我为什么吗?
" "从char [2]转换为char *,然后作为指针转换为int,并将其作为int转换为bool。
我对Qt不是很熟悉,但如果QString的构造函数(使用char [N]或char *参数)是显式的,则只有在编写以下内容时才会调用第一个构造函数:
DB_Variable foo("some_name", QString{ " " });
                   // HERE:  ^^^^^^^^     ^

最简单的解决方案是为您的DB_Variable类添加第三个构造函数。您可以使用多种方式实现这一点,但如果您希望将空值(默认情况下)设置为" ",则应编写类似于以下代码的代码:
DB_Variable(QString name):
name(name),value_string(" "), var_type(DB_STRING){}

客户端代码:
DB_Variable foo("some_name"); // create variable with empty value (actually " " value)

1
字符串" "只是一个char*。将其转换为bool比使用用户定义的转换到QString更容易。

2
s/char*/const char[2]. 不过在进入任何一个之前,它仍然需要衰变。 - chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接