-1

foo.h

#ifndef FOO_H
#define FOO_H

class Foo
{
    int fooObj1;
    bool fooObj2;
public:
    Foo(int input1);
};

#endif

foo.cpp

#include "foo.h"

Foo::Foo(int input1)
{
    fooObj1 = input1;
    // some code logic to decide the value of fooObj2 (an example)
    // so I can't really do member initialization list.
    fooObj2 = (fooObj1 % 2 == 0);
}

所以我正在关注一个教程,他们告诉我打开[-Weffc++]并将警告视为错误。但是当我这样做时,请[-Weffc++]发出警告: 'Foo::fooObj1' should be initialized in the member initialization list [-Weffc++]'Foo::fooObj2' should be initialized in the member initialization list [-Weffc++]. 但是我不能在这个项目中真正做成员初始化列表。那么我该如何重新接受这个警告呢?

4

4 回答 4

2
Foo::Foo(int input1)
   : fooObj1(input1)
   , fooObj2(input1 % 2 == 0)
{
}

请注意,fooObj2 的值是根据 input1 参数计算的,而不是 fooObj1 的值。原因是,如果您要更改标题中的顺序:

class Foo
{
    bool fooObj2;
    int fooObj1;
public:
    Foo(int input1);
};

如果您从 fooObj1 计算 fooObj2,您最终会进入未初始化的 fooObj1 内存。成员按照它们在类中出现的顺序进行初始化,而不是按照它们在构造函数的初始化列表中出现的顺序。

于 2021-10-19T09:30:08.767 回答
1
    
Foo::Foo(int input1) : fooObj1(input1), fooObj2(0 == input1 % 2) {}
于 2021-10-19T07:56:54.763 回答
1

-Weffc++产生一些偏执的警告,但有一个你想要遵循的理想。例如,你总是可以做部分列表:

Foo::Foo(int input1) : fooObj1(input1) /*, fooObj2() still can be here */
{
    // some code logic to decide the value of fooObj2 (an example)
    // so I can't really do member initialization list.
    fooObj2 = (fooObj1 % 2 == 0);
}

请注意,构造函数主体中的代码不是初始化。这是一个任务。类的成员仍然按照其声明的顺序使用实现定义的或不确定的值进行初始化。

在某些多线程情况下,如果 Foo 的成员是原子的并且某些东西可能同时访问它们,则差异可能很重要。

分析逻辑很重要,它是否需要分支,它实际上是编译时已知的常量吗?你可以使用简单的三元进行初始化吗?

在复杂的情况下 fooObj2,甚至可能是另一个类类型的对象,其自身的 ctor 隐藏了“复杂逻辑”,以避免确定初始化顺序时出现问题。

于 2021-10-19T09:53:53.687 回答
1

消除警告的两种解决方案。

解决方案 1

制作一些静态方法,例如CalculateFooObj2InitialValue,并在成员初始化列表中使用它。

Foo::Foo(int input1):
  fooObj1(input1),
  fooObj2(CalculateFooObj2InitialValue(input1)) {
  ...  
}

解决方案 2

使用成员初始化fooObj2列表中的默认值进行初始化,但意义不大。然后再计算一个有意义的初始值并赋值。

Foo::Foo(int input1):
  fooObj1(input1),
  fooObj2{} {
  // some code logic to decide the value of fooObj2 (an example)
  // so I can't really do member initialization list.
  fooObj2 = (fooObj1 % 2 == 0);
}
于 2021-10-19T11:41:31.923 回答