【问题标题】:Using the explicit keyword for one argument constructors对一个参数构造函数使用显式关键字
【发布时间】:2014-10-19 01:29:07
【问题描述】:

我发现另一个很久以前回答的问题,并没有真正理解其中一个答案。 Eddie's answer,在他的回答中他说如果你使用String mystring = 'x';,那么x 将被转换为一个整数并调用String(int)。为什么这个语句调用构造函数?我认为为了使用构造函数,您必须使用像String mystring('x') 这样的语句。赋值运算符= 是否等同于创建对象的新实例?

【问题讨论】:

  • = 不是该语句中的运算符。
  • @chris 你能解释一下= 在那个声明中是什么吗?我一直认为它是将左侧分配给右侧。
  • 它根本不是运算符,只是同一符号的另一种用法。就像如果f 是一个函数,f(a,b) 不使用逗号运算符,或者int *p 不使用解引用运算符或乘法运算符。这称为复制初始化。
  • @chris 我很难找到这方面的文档,比如如果有一个接受 2 个参数的构造函数,在这种情况下是否可以使用 =

标签: c++ class object constructor explicit


【解决方案1】:

T t(x) 称为直接初始化T t = x 称为复制初始化。即使使用了=,复制初始化也不使用赋值。因为它是在声明时使用的,所以它是一种初始化形式。

在复制初始化期间,如果初始化器的类型与正在创建的对象的类型不匹配,则搜索并调用一个 converting-constructor 并调用(如果可用)来转换初始化器.结果是一个临时实例,可以复制或移动构造到对象中。

例如,由于'x'String 的类型不匹配,因此搜索适当的构造函数并将'x' 转换为String 实例。选择了String::String(int) 构造函数,结果是一个临时实例String('x')。然后(因为临时是右值),如果移动构造函数可用,临时将被移动构造成mystring,否则复制构造。

如果有一个接受 2 个参数的构造函数,在这种情况下是否可以使用=

是的,您可以使用 braced-initializer 来提供多个参数。它将为每个参数搜索最佳构造函数:

struct Square
{
    Square(float width, float height);
};

int main()
{
    // copy-initialization:
    Square square = {2.5, 4.0}; // calls Square(2.5, 4.0)
}

但请注意,如果有一个构造函数采用相同类型的std::initializer_list,那么它将覆盖上面显示的行为:它将改为调用初始化列表构造函数。

【讨论】:

  • 只是对您刚刚展示的示例的快速查询:没有像move-initialization 这样的东西吗?如果是,那么我认为,您的评论应该说move-initialization 而不是copy-initialization,因为临时将被移动以创建square 对象。我是对的还是错过了什么?
  • @aniliitb10 是的,说移动初始化会更准确,但是当我们说“复制”时,我们的意思是它可能是实际复制或移动。但事实证明,在我展示的示例中,由于我使用的是列表初始化,因此不会发生复制/移动。这与使用直接列表初始化 (Square square{2.5, 4.0}) 没有什么不同。
猜你喜欢
  • 2016-07-18
  • 2010-11-10
  • 2018-04-26
  • 2017-12-25
  • 1970-01-01
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 2016-12-31
相关资源
最近更新 更多