在初始化列表中调用私有函数时,是否存在未定义的行为?

发布于 2024-08-26 06:25:40 字数 837 浏览 8 评论 0原文

考虑以下代码:

struct Calc
{
   Calc(const Arg1 & arg1, const Arg2 & arg2, /* */ const ArgN & argn) :
      arg1(arg1), arg2(arg2), /* */ argn(argn), 
      coef1(get_coef1()), coef2(get_coef2()) 
   {
   }

   int Calc1();
   int Calc2();
   int Calc3();

private:
  const Arg1 & arg1;
  const Arg2 & arg2;
  // ...
  const ArgN & argn;

  const int coef1; // I want to use const because 
  const int coef2; //      no modification is needed.

  int get_coef1() const {
     // calc coef1 using arg1, arg2, ..., argn;
     // undefined behavior?     
  }
  int get_coef2() const {
     // calc coef2 using arg1, arg2, ..., argn and coef1;
     // undefined behavior?
  }

};

当我调用 get_coef1get_coef2 时,struct Calc 未完全定义 该代码有效吗?我可以得到UB吗?

Consider the following code:

struct Calc
{
   Calc(const Arg1 & arg1, const Arg2 & arg2, /* */ const ArgN & argn) :
      arg1(arg1), arg2(arg2), /* */ argn(argn), 
      coef1(get_coef1()), coef2(get_coef2()) 
   {
   }

   int Calc1();
   int Calc2();
   int Calc3();

private:
  const Arg1 & arg1;
  const Arg2 & arg2;
  // ...
  const ArgN & argn;

  const int coef1; // I want to use const because 
  const int coef2; //      no modification is needed.

  int get_coef1() const {
     // calc coef1 using arg1, arg2, ..., argn;
     // undefined behavior?     
  }
  int get_coef2() const {
     // calc coef2 using arg1, arg2, ..., argn and coef1;
     // undefined behavior?
  }

};

struct Calc is not completely defined when I call get_coef1 and get_coef2
Is this code valid? Can I get UB?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

最终幸福 2024-09-02 06:25:40

12.6.2.8:可以为正在构造的对象调用成员函数(包括虚拟成员函数,10.3)。相似地,
正在构造的对象可以是 typeid 运算符(5.2.8)或dynamic_cast(5.2.7)的操作数。然而,
如果这些操作是在构造函数初始化程序中执行的(或者在从构造函数初始化程序直接或间接调用的函数中)
在基类的所有内存初始化程序完成之前,操作的结果是未定义的。

因此,您可以通过这种方式初始化类成员,但不能初始化基类。而且,正如其他人指出的那样,如果您的函数使用成员的某些值,您应该了解成员初始化顺序。

12.6.2.8: Member functions (including virtual member functions, 10.3) can be called for an object under construction. Similarly,
an object under construction can be the operand of the typeid operator (5.2.8) or of a dynamic_cast (5.2.7). However,
if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer)
before all the mem-initializers for base classes have completed, the result of the operation is undefined.

So you can initialize your class members this way, but not base classes. And, as others pointed, you should be aware of members initialization order, if your function uses some of their values.

懷念過去 2024-09-02 06:25:40

由于您的计算所依赖的变量在调用时已经初始化,因此它不应该是未定义的行为。请参阅问题了解相关信息。

Since the variables your calculation depend on are already initialized at the time of the call, it should not be undefined behavior. See this question for related information.

清眉祭 2024-09-02 06:25:40

不是它不是未定义的,而是您必须绝对确定这些成员函数仅使用初始化值。另请注意,值按照它们在类中出现的顺序进行初始化,而不是按照它们在初始化列表中出现的顺序进行初始化。例如:

struct Foo
{
  int a, b;
  int c;
  Foo(): c(1), a(1), b(1) {}
};

在该构造函数中,变量按照a、b、c的顺序初始化,列表中的顺序没有任何意义。因此,如果您希望使用 bc 上的一些计算来初始化 a 的值,那么您需要移动 a 的声明code>a 到 bc 之后的点。

Not it's not undefined, but you have to be absolutely sure that those member functions are only using initialised values. Note also that values are initialised in the order that they appear in the class not the order they appear in the initialisation list. For example:

struct Foo
{
  int a, b;
  int c;
  Foo(): c(1), a(1), b(1) {}
};

In that constructor, the variables are initialised in the order a, b, then c, the order in the list means nothing. So if you want the value of a to be initialised using some calculation on b and c then you'll need to move the declaration of a to a point after that of b and c.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文