这是演员还是建筑?
读完教科书上的一些内容后,我有点困惑。关于代码:
void doSomeWork(const Widget& w)
{
//Fun stuff.
}
doSomeWork(Widget(15));
doSomeWork()
采用 const Widget&
参数。教科书《Effective C++ III》指出,这将创建一个临时 Widget 对象以传递给 doSomeWork。它说这可以替换为:
doSomeWork(static_cast<Widget>(15));
因为两个版本都是强制转换 - 第一个显然只是函数风格的 C 强制转换。我本以为 Widget(15)
会调用一个带有一个整数参数的小部件的构造函数。
在这种情况下构造函数会被执行吗?
I'm a little confused after reading something in a textbook. Regarding the code:
void doSomeWork(const Widget& w)
{
//Fun stuff.
}
doSomeWork(Widget(15));
doSomeWork()
takes a const Widget&
parameter. The textbook, Effective C++ III, states that this creates a temporary Widget object to pass to doSomeWork. It says that this can be replaced by:
doSomeWork(static_cast<Widget>(15));
as both versions are casts - the first is just a function-style C cast apparently. I would have thought that Widget(15)
would invoke a constructor for widget taking one integer parameter though.
Would the constructor be executed in this case?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
在 C++ 中,这种表达式是强制转换的一种形式,至少在语法上是如此。即,您使用 C++ 函数转换语法
Widget(15)
来创建Widget
类型的临时对象。即使您使用多参数构造函数构造临时对象(如
Widget(1, 2, 3)
),它仍然被视为函数转换表示法的变体(请参阅5.2.3)换句话说,您的“这是强制转换还是构造”问题的表述不正确,因为它意味着强制转换和“构造”之间的相互排他性。它们并不相互排斥。事实上,每个类型转换(无论是显式强制转换还是更隐式的转换)无非是目标类型的新临时对象的创建(“构造”)(可能不包括某些引用初始化)。
顺便说一句,函数式转换表示法主要是 C++ 表示法。 C 语言没有函数式类型转换。
In C++ this kind of expression is a form of a cast, at least syntactically. I.e. you use a C++ functional cast syntax
Widget(15)
to create a temporary object of typeWidget
.Even when you construct a temporary using a multi-argument constructor (as in
Widget(1, 2, 3)
) it is still considered a variation of functional cast notation (see 5.2.3)In other words, your "Is this a cast or a construction" question is incorrectly stated, since it implies mutual exclusivity between casts and "constructions". They are not mutually exclusive. In fact, every type conversion (be that an explicit cast or something more implicit) is nothing else than a creation ("construction") of a new temporary object of the target type (excluding, maybe, some reference initializations).
BTW, functional cast notation is a chiefly C++ notation. C language has no functional-style casts.
短:是的。
Long:
,例如:
你总是可以自己测试这些东西
Short: Yes.
Long:
You can always test those things yourself, by doing e.g.:
which is outputting
是的,两者都是:)。强制转换是一种语法结构(即您键入的内容)。在这种情况下,构造函数作为强制转换的结果而被调用。很像构造函数会因键入而被调用
Yes, it is both :). A cast is a syntactic construct (i.e. something you type). In this case, a constructor is invoked as a consequence of the cast. Much like a constructor would be invoked as a consequence of typing
Widget(15)
和static_cast(15)
都是强制转换或转换运营商,如果您愿意的话。两者都创建指定的新对象
类型,通过将
15
转换为Widget
。由于15
没有任何转换运算符,执行此转换的唯一方法是
分配必要的内存(在堆栈上)并调用
适当的构造函数。这实际上与
double(15)
没有什么不同和
static_cast(15)
,只不过我们通常不会想到double
具有构造函数(但生成的double
是一个新的对象,与
15
不同,后者的类型为int
)。Both
Widget(15)
andstatic_cast<Widget>(15)
are casts, or conversionoperators, if you prefer. Both create a new object of the designated
type, by converting
15
into aWidget
. Since15
doesn't have anyconversion operators, the only way to do this conversion is by
allocating the necessary memory (on the stack) and calling the
appropriate constructor. This is really no different that
double(15)
and
static_cast<double>(15)
, except that we usually don't think ofdouble
as having a constructor (but the resultingdouble
is a newobject, distinct from the
15
, which has typeint
).你说:
第一个不会在 C 中编译,它不是 C 风格。 C 风格看起来像
(Widget)15
。这里,使用Widget::Widget(int)
创建临时对象。因此,它不是C型演员。
You said:
The first would not compile in C, it's not C-style. C-style looks like
(Widget)15
. Here, the temporary object is created, usingWidget::Widget(int)
.Therefore, it is not a C-style cast.
是的当然。任何采用单个参数的构造函数都将被视为转换构造函数。您的构造函数已经采用单个
int
参数,以便编译器可以“隐式”调用此构造函数来匹配参数(值为15
,即int
)。有一个简单的技巧可以防止此类错误,只需在构造函数之前使用关键字
explicit
即可。查看此了解更多信息。
Yes, of course. Any constructor takes a single parameter would be considered as CONVERSION CONSTRUCTOR. Your constructor is already taking a single
int
parameter, so that the compiler can "implicitly" call this constructor to match the argument (with the value15
, which isint
).There is a simple trick to prevent such errors, just use the keyword
explicit
before your constructor.Check this for more information.
是啊。您可以替换
为
因为它将被编译器替换回来 :D
当您将
int
转换为Widget
时,编译器会查找Widget::Widget(int);并将其放在那里。
Yeeeah. You can replace
with
Because it will be replaced back by compiler :D
When you cast
int
toWidget
compiler looks forWidget::Widget(int);
and place it there.