Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这是石膏还是建筑?_C++_Casting_Constructor - Fatal编程技术网

C++ 这是石膏还是建筑?

C++ 这是石膏还是建筑?,c++,casting,constructor,C++,Casting,Constructor,读了课本上的内容后,我有点困惑。关于守则: void doSomeWork(const Widget& w) { //Fun stuff. } doSomeWork(Widget(15)); doSomeWork()接受一个const小部件&参数。教科书,有效的C++ III,说明这会创建一个临时的小部件对象,以传递给DOM。它说,这可以由以下内容取代: doSomeWork(static_cast<Widget>(15)); doSomeWork(静态铸造(1

读了课本上的内容后,我有点困惑。关于守则:

void doSomeWork(const Widget& w)
{
    //Fun stuff.
}

doSomeWork(Widget(15));
doSomeWork()
接受一个
const小部件&
参数。教科书,有效的C++ III,说明这会创建一个临时的小部件对象,以传递给DOM。它说,这可以由以下内容取代:

doSomeWork(static_cast<Widget>(15));
doSomeWork(静态铸造(15));
因为两个版本都是强制转换——第一个版本显然只是一个函数样式的C强制转换。我本以为
Widget(15)
会调用一个构造函数来获取一个整数参数

在这种情况下会执行构造函数吗?

您说过:

第一个只是一个函数类型的C cast

第一个不会用C编译,它不是C风格。C样式看起来像
(小部件)15
。这里,使用
Widget::Widget(int)
创建临时对象


因此,它不是C型铸造。

Yeeeah。你可以替换

Widget(15)

static_cast(15)
因为它将被编译器D替换回来


当您将
int
转换为
Widget
时,编译器将查找
Widget::Widget(int)并放置在那里。

C++中,这种表达式至少是语法上的一种形式。也就是说,使用C++函数CAST语法<代码>控件(15)< /C> >创建一个临时的对象:类型>代码>小部件< /代码> .< 即使使用多参数构造函数(如
小部件(1、2、3)
构造临时变量,它仍然被认为是函数强制转换表示法的变体(参见5.2.3)

换句话说,您的“这是一个类型还是一个结构”问题表述错误,因为它暗示了类型和“结构”之间的相互排斥性。它们不是相互排斥的。事实上,每个类型转换(无论是显式转换还是更隐式的转换)都只不过是创建(“构造”)目标类型的新临时对象(可能不包括某些引用初始化)

Short:是的

长:

您可以自己测试这些东西,例如:

#include <iostream>

struct W
{
    W( int i )
    {
        std::cout << "W(" << i << ")\n";
    }
};

int main(int argc, const char *argv[])
{
    W w(1);
    W(2);
    static_cast<W>(3);
}
是的,两者都是:)。强制转换是一种语法构造(即您键入的内容)。在这种情况下,将调用构造函数作为强制转换的结果。很像一个构造函数会被调用作为一个结果的类型

Widget w(15);
Widget(15)
static\u cast(15)
都是强制转换或转换 接线员,如果你愿意的话。两者都创建指定对象的新对象 通过将
15
转换为
小部件来键入。因为
15
没有任何 转换运算符,执行此转换的唯一方法是 分配必要的内存(在堆栈上)并调用 适当的构造函数。这与
double(15)
和静态演员(15)
,除了我们通常不会想到的
double
作为一个构造函数(但是得到的
double
是一个新的
对象,与类型为
int
15
不同

当然可以。任何接受单个参数的构造函数都将被视为转换构造函数。您的构造函数已经使用了一个
int
参数,因此编译器可以“隐式”调用此构造函数以匹配参数(值
15
,即
int

有一个简单的技巧可以防止此类错误,只需在构造函数之前使用关键字
explicit


查看更多信息。

@MSalters:对于大多数类型,强制转换与创建(临时)对象没有什么不同。
W(1)
W(2)
W(3)
Widget w(15);