在一行中初始化多个私有变量

Initializing many private variables in one line

本文关键字:变量 初始化 一行      更新时间:2023-10-16

我正在处理的遗留代码如下:

class Foo {
  public:
    Foo();
  private:
    bool a1, a2, a3 /*, ...*/, a50;
};
Foo::Foo() {
  a1 = a2 = a3 /* = ... */ = a50 = false;
}

这太乱了。是否有一种方法可以将同一时间的所有私有变量默认为与上述不同的单个值?我不想使用初始化列表,因为变量太多了。

我知道bool的默认构造函数分配false -这可以利用吗?

有许多可能的方法可以做到这一点,但它们都非常相似。无论如何,你将使用不同的形式为每个变量赋值。

我认为最好的主要方法是在构造函数中逐行分配所有变量。也许它不紧凑,但它最有意义,你总是可以很容易地看到你的变量默认值:

Foo::Foo() {
    a1 = false;
    a2 = false;
    /*...*/
    a50 = false;
} 

另一个方法是你描述的,使用赋值操作符:

Foo::Foo() {
    a1 = a2 = a3 /* = ... */ = a50 = false;
}

另一个允许在构造函数声明后初始化变量:

Foo::Foo() : 
    a1(false),
    a2(false),
    /*...*/
    a50(true)
    { }

如果我忘记了任何方法,请把它写在注释中

class Foo
{
private:
    bool a1{}, a2{}, /*...,*/ a50{};
};

try with this

Foo::Foo (bool aa) : a1 (aa) , a2 (aa), a3 (aa),/*......*/a50(aa){}

你可以有另一个类(在单独的头文件中),如下所示:

class myBool {
  public:
    myBool(int x = 1) { _m = x; }
    operator bool() const { return  0 < _m; }
  private:
    int _m;
};

,你可以在你的文件中添加以下

#include "myBool.h"
#define bool myBool

这将初始化所有bool值为myBool中设置的默认值。您可能需要向myBool类添加更多的方法,以便将其用作完整的数据类型。以上是解释答案的最低限度。

这是我目前为止看到的另一个解决方案,如果它对你有用的话。

把你想要大规模初始化的数据放在它自己的结构体中,默认为false/0值:

struct MyData
{
    bool a, b, c, d;
    std::string e, f;
};

现在从这个结构体继承(私有或其他),并在构造函数的初始化列表中显式初始化它:

class MyClass : private MyData
{
public:
    MyClass()
        : MyData()
    {
    }
};

这将所有的bool设置为false,字符串为空,所有int型变为0,指针变为null,等等

如果忘记将结构体显式地放入初始化列表中,则其某些成员可能未初始化。

确认在c++中总是需要更多的工作来偷懒…

#include <iostream>
#include <utility>

template<class Tuple, std::size_t...Is>
void zero_out_impl(Tuple& t, std::index_sequence<Is...>)
{
    using expand = bool[];
    (void) expand { false, (std::get<Is>(t) = false)... };
}
template<class...Args>
void zero_out(std::tuple<Args...> t)
{
    zero_out_impl(t, std::index_sequence_for<Args...>());
}
struct lots_of_bools {
    lots_of_bools()
    {
        zero_out(std::tie(a,b,c,d,e,f,g,h,i,j));
    }
private:
    bool a,b,c,d,e,f,g,h,i,j;
};
auto main() -> int
{
    lots_of_bools x;
    return 0;
}

还有另一种方法——将bool封装在默认构造它的包装器中。

#include <iostream>

struct auto_false
{
    auto_false(bool initial = false) : value(initial) {};
    operator bool() const { return value; }
    operator bool& () { return value; }
private:
    bool value;
};
struct lots_of_bools {
    lots_of_bools()
    {
    }
    bool value_of_f() const {
        return f;
    }
    void set_f(bool val) {
        f = val;
    }
private:
    auto_false a,b,c,d,e,f,g,h,i,j;
};
using namespace std;
auto main() -> int
{
    lots_of_bools x;
    cout << x.value_of_f() << endl;
    x.set_f(true);
    cout << x.value_of_f() << endl;
    return 0;
}
输出:

0
1