显式赋值vs隐式赋值

Explicit Assignment vs Implicit Assignment

本文关键字:赋值 vs      更新时间:2023-10-16

我正在阅读c++教程,但它实际上并没有给我两者之间的区别(除了语法)。以下是教程中的一段话。

您还可以在声明时为变量赋值。当我们使用赋值操作符(等号)为变量赋值符号),它被称为显式赋值:

int nValue = 5; // explicit assignment

你也可以使用隐式赋值给变量赋值:

int nValue(5); // implicit assignment

尽管隐式赋值看起来很像函数调用编译器跟踪哪些名称是变量,哪些是变量函数,以便它们可以正确地解析。

有区别吗?哪个更受欢迎?

对于基本类型,如int;第二种使用具有构造函数的类型,因为它使构造函数调用显式。

。,如果您定义了可以由单个int构造的class Foo,则

Foo x(5);

优于

Foo x = 5;

(无论如何,当传递多个参数时,您需要前一种语法,除非您使用Foo x = Foo(5, "hello");,这很难看,看起来像正在调用operator=。)

对于基本类型两者都是等效的,只有对于用户定义的类类型才有区别。在这两种情况下,执行的代码将是相同的(在执行基本优化之后),但是如果我们初始化的元素不是我们正在构造的类型,则对类型的要求是不同的。

复制初始化 (T t = u;)相当于从T类型的临时对象(已隐式地从u转换为t)进行复制构造。另一方面,直接初始化等价于直接调用相应的构造函数。

虽然在大多数情况下没有区别,但如果接受u的构造函数被声明为explicit,或者复制构造函数不可访问,则复制初始化将失败:

struct A {
   explicit A( int ) {}
};
struct B {
   B( int ) {}
private:
   B( B const & );
};
int main() {
   A a(1);      // ok
   B b(1);      // ok
// A a2 = 1;    // error: cannot convert from int to A
// B b2 = 1;    // error: B( B const & ) is not accessible
}

在某些历史背景下,最初的基本类型必须用copy-initialization初始化。当*initializer-list*s被添加到语言中用于初始化类的成员属性时,决定基本类型应该使用与类相同的语法进行初始化,以保持初始化列表中的语法统一和简单。同时,允许通过复制初始化对类进行初始化,使得用户定义的类型更接近基本类型。两种初始化格式的差异是很自然的:int a = 5.0;被处理为从5.0int的转换,然后从int初始化a。用户定义的类型也是如此:将T u = v;处理为从vT的转换,然后从转换后的值复制u的构造。

在声明变量和初始化变量时,它们在该上下文中在功能上是相同的。我通常把这两者称为:

int nValue = 5; // assignment syntax

int nValue(5); // construction syntax

对于基本类型,我更喜欢赋值而不是构造,因为它更自然,特别是对于那些用其他语言编程的人。

对于类类型,我更喜欢构造语法,因为它避免了构造函数的存在。