【问题标题】:What's the difference between explicit and implicit assignment in C++C++中显式赋值和隐式赋值有什么区别
【发布时间】:2011-03-04 17:24:49
【问题描述】:
int value = 5; // this type of assignment is called an explicit assignment
int value(5); // this type of assignment is called an implicit assignment

它们之间有什么区别(如果有的话),在什么情况下显式和隐式赋值有区别以及如何区别?


http://weblogs.asp.net/kennykerr/archive/2004/08/31/Explicit-Constructors.aspx

编辑:实际上我刚刚发现这篇文章,它使整个事情变得更加清晰......它提出了另一个问题,如果你(一般)标记构造函数采用单个参数原始类型 - numeric/bool/string - 显式,其余部分保持原样(当然要注意诸如 (int, SomeType = SomeType()) 之类的构造函数之类的陷阱?

【问题讨论】:

  • 这闻起来像家庭作业。如果是,请标记它。
  • 不是作业,只是我很久以前的笔记,我从未调查过。无论如何,将某事标记为作业有什么作用?
  • 这清楚地表明问题是家庭作业。 =] 通常,回答问题的人更愿意给出提示而不是提供完整的答案。
  • 只是为了记录,我有这个问题,这不是功课。 :) 我想这只是学习曲线上的一点。

标签: c++ explicit-constructor


【解决方案1】:

这些都不是任何类型的赋值——它们都是初始化。第一个使用复制初始化,第二个直接初始化。 (FWIW,我很确定我以前从未听说过“显式赋值”或“隐式赋值”这些术语)。

编辑:(主要是为了回应 Nathan 的评论):

这是您评论中代码的更正版本:

#include <iostream>

struct Foo { 
    Foo() { 
        std::cout << "Foo::ctor()" << std::endl; 
    } 
    Foo(Foo const& copy) { 
        std::cout << "Foo::cctor()" << std::endl; 
    } 
    Foo& operator=(Foo const& copy) { 
        std::cout << "foo::assign()" << std::endl; 
        return *this; 
    } 
};

int main(int, const char**) { 
    Foo f; 
    Foo b(f); 
    Foo x = b;
    return 0; 
}

运行结果应该是:

Foo::ctor()
Foo::cctor()
Foo::cctor()

如果你运行它并得到一个foo::assign(),扔掉你的编译器并得到一个可以工作的(哦,让我们知道它是什么编译器坏得这么厉害)!

【讨论】:

  • 不是必然为真。使用 POD 类型,是的,您的陈述是准确的。如果所讨论的类型是用户定义的,那么完全有可能存在一个用户定义的赋值运算符来执行转换而没有类似的复制构造函数。奇怪,是的。不过,有可能。
  • 还有,第一个是赋值。只有第二个是初始化。第一个可以并且几乎肯定会被内联到等效的副本初始化并不会减损它是一个赋值。复制初始化和复制分配相同的假设是有缺陷的,不能保证。
  • @Nathan:这个答案是正确的。 §8.5/12 将“复制初始化”定义为T x = a; 形式的任何初始化,而“直接初始化”定义为T x(a); 形式的任何初始化。两者都在初始化。
  • @Nathan,你倒退了。富吧 = baz;永远不会导致赋值(除非构造函数恰好根据 operator= 实现),它始终是复制初始化。它最多会产生等同于Foo bar(static_cast&lt;Foo&gt;(baz)); 的代码,至少会产生等同于Foo bar(baz); 的代码。它永远不会产生等同于Foo bar; bar = baz; 的代码。换句话说,没有任务正在进行。请参阅 C++0x 标准草案 (N3092) 的第 8.5 14-16 节(引用这一点是因为我没有当前标准的副本,但这并没有改变)。
  • @Nathan Ernst:完全不正确。两种形式都不会调用赋值运算符。这些初始化始终由构造函数处理(可能涉及转换运算符),但如果缺少某些构造函数,则代码将无法编译。永远不会使用分配。
【解决方案2】:

如果一个类有一个标记为“显式”的构造函数,它们会有所不同。然后,其中之一不起作用。

否则,没有区别。

【讨论】:

    【解决方案3】:

    只有第一个是作业。它们都是初始化。

    编辑:实际上,我错了。也不是赋值。

    【讨论】:

    • 这些都不是分配。赋值和初始化是互斥的术语。
    猜你喜欢
    • 1970-01-01
    • 2015-06-27
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 2018-04-20
    • 2010-10-01
    相关资源
    最近更新 更多