gpt4 book ai didi

c++ - 在使用相同名称的构造函数参数初始化成员变量时,=和{}之间的区别

转载 作者:行者123 更新时间:2023-12-02 10:19:00 40 4
gpt4 key购买 nike

按照这个answer,为成员变量和构造函数参数使用相同的名称是可以的。因此,在进行了一些调试之后,我发现了以下代码为何不起作用的原因(该类的操作成员从未初始化过,从而导致switch语句失败)。

#include <cstdio>
#include <cstdlib>

enum class Operator {
Add,
Subtract,
Multiply,
Divide
};

class Calculator {
Operator operation;
public:
Calculator(Operator operation) {
operation = operation;
}

int calculate(int a, int b) {
switch (operation) {
case Operator::Add: {
return a+b;
}
case Operator::Subtract: {
return abs(a-b);
}
case Operator::Multiply: {
return a*b;
}
case Operator::Divide: {
return a/b;
}

}
}
};

int main() {
Calculator calculator{Operator::Add};
int a = 100;
int b = 20;
printf("%d + %d = %d\n", a, b, calculator.calculate(a, b));
}

用构造函数内部的 operation = operation替换 operation{operation}行解决了该问题,但是我仍然不明白为什么 operation = operationoperation{operation}相比产生错误的结果,并且在构造函数初始化的上下文中两者之间有什么区别;

最佳答案

在两个标识符相同的特殊情况下,赋值和成员初始化之间的区别:
operation = operation;是从参数operation到参数operation的赋值。参数operation使成员operation黯然失色。

要解决此问题,您必须编写this->operation = operation;

class Calculator {
Operator operation;
public:
Calculator(Operator operation) {
this->operation = operation;
}
};

除此之外,成员初始化 operation(operation)operation{operation}是可取的。
class Calculator {
Operator operation;
public:
Calculator(Operator operation):
operation{operation}
{
}
};

之所以可行,是因为在成员初始化列表中,作用域还没有包含参数列表(类作用域),但是成员初始化器中的表达式在作用域中使用参数(成员函数作用域)进行了解析。

经过草率的解释后,我从 cppreference.com 撤回了 Constructors and member initializer lists:

The body of a function definition of any constructor, before the opening brace of the compound statement, may include the member initializer list, whose syntax is the colon character :, followed by the comma-separated list of one or more member-initializers, each of which has the following syntax


class-or-identifier ( expression-list(optional) ) (1)


class-or-identifier brace-init-list (2) (since C++11)


parameter-pack ... (3) (since C++11)


1) Initializes the base or member named by class-or-identifier using direct initialization or, if expression-list is empty, value-initialization

2) Initializes the base or member named by class-or-identifier using list-initialization (which becomes value-initialization if the list is empty and aggregate-initialization when initializing an aggregate)

3) Initializes multiple bases using a pack expansion

  • class-or-identifier - any identifier, class name, or decltype expression that names a non-static data member, a direct or virtual base, or (for delegating constructors) the class itself

  • expression-list - possibly empty, comma-separated list of the parameters to pass to the constructor of the base or member

  • braced-init-list - brace-enclosed list of comma-separated initializers and nested braced-init-lists

  • parameter-pack - name of a variadic template parameter pack



即用于初始化
  • 仅类标识符本身(用于委派构造函数调用)
  • 基类标识符(用于基类构造函数调用)
  • 和数据成员(用于成员初始化程序)

  • 被考虑但不考虑参数(具有任何名称)。

    在成员初始化器(括号或花括号)内,使用成员函数的常用名称解析,因此,参数可能会使具有相同名称的成员黯然失色。

    关于c++ - 在使用相同名称的构造函数参数初始化成员变量时,=和{}之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61038148/

    40 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com