【问题标题】:Initializing many private variables in one line在一行中初始化多个私有变量
【发布时间】:2015-10-07 17:56:24
【问题描述】:

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

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

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

这很混乱。有没有办法将同一时间的所有私有变量默认为与上述不同的单个值?我不想使用初始化列表,因为变量太多。

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

【问题讨论】:

  • 只是一个想法,但不是有 50 个布尔值,为什么不bool flags[50]{ false };
  • @NathanOliver 我很乐意这样做,但 PM 可能会争辩说这些变量会丢失一个有意义的标识符。
  • 您可能想做memset( this, 0, sizeof( Foo ) )....即使它可能在您的特定示例中有效,但不建议这样做:stackoverflow.com/questions/1975916/…
  • 确实,小心 memset!
  • @erip 我强烈主张使用布尔数组。还是变量名称与您的示例中的名称不同?

标签: c++ constructor default-constructor


【解决方案1】:

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

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

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

您描述的另一种方法是使用分配运算符:

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

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

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

如果我忘记了任何方法,请将其写入 cmets。

【讨论】:

  • 你没有提到使用数组a[50] { false };
  • 我只是阅读问题的 cmets。在那里,作者说他对具有有意义名称的变量赋值感兴趣。据我了解,例如选择了相关变量的名称。
【解决方案2】:
class Foo
{
private:
    bool a1{}, a2{}, /*...,*/ a50{};
};

【讨论】:

    【解决方案3】:

    试试这个

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

    【讨论】:

    • 如何不那么凌乱?
    【解决方案4】:

    您可以拥有另一个类(在单独的标题中),如下所示。

    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 类添加更多方法以将其用作完整的数据类型。以上是解释答案的最低限度。

    【讨论】:

      【解决方案5】:

      这是我迄今为止看到的解决方案的替代解决方案,以防它对您有用。

      将要批量初始化的数据放入其自身结构中的默认 false/0 值:

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

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

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

      这会将所有布尔值设置为 false,字符串为空,任何整数变为 0,指针变为空,等等

      如果您忘记将结构显式放入初始化列表中,它的某些成员可能未初始化。

      【讨论】:

        【解决方案6】:

        确认在 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;
        }
        

        【讨论】:

        • 不知道这比简单地在初始化列表中列出它们更有效。
        • 正是我第一行的意思!! :)
        【解决方案7】:

        这是另一种方式 - 将 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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-19
          • 2011-04-02
          相关资源
          最近更新 更多