显式赋值与隐式赋值

时间:2011-07-19 18:03:36

标签: c++ implicit explicit

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

  

您还可以在声明时为变量赋值。什么时候我们   使用赋值运算符为变量赋值(等于   标志),它被称为明确的任务:

int nValue = 5; // explicit assignment
     

您还可以使用隐式赋值为变量赋值:

int nValue(5); // implicit assignment
     

即使隐式赋值看起来很像函数调用,但是   编译器跟踪哪些名称是变量,哪些是   功能,以便他们可以正确解决。

有区别吗?一个比另一个更受欢迎吗?

3 个答案:

答案 0 :(得分:12)

首先使用int这样的原始类型;第二个类型具有构造函数,因为它使构造函数调用显式。

,例如,如果您定义了可以从单个class Foo构建的int,那么

Foo x(5);

优先于

Foo x = 5;

(当传递多个参数时,无论如何都需要以前的语法,除非你使用的是Foo x = Foo(5, "hello");,这看起来很简单,看起来正在调用operator=。)

答案 1 :(得分:6)

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

复制初始化T t = u;)等同于从T隐式转换为{{u的临时类型t的复制构造1}}。另一方面, direct-initialization 相当于直接调用相应的构造函数。

虽然在大多数情况下没有区别,如果u的构造函数被声明为explicit copy-constructor 无法访问,那么复制初始化将失败:

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
}

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

答案 2 :(得分:2)

当您声明变量并初始化它时,它们在该上下文中的功能相同。我通常将这两个称为:

int nValue = 5; // assignment syntax

int nValue(5); // construction syntax

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

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