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

Posted

技术标签:

【中文标题】在一行中初始化多个私有变量【英文标题】: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 ) )....即使它可能在您的特定示例中有效,但不建议这样做:***.com/questions/1975916/… 确实,小心 memset! @erip 我强烈主张使用布尔数组。还是变量名称与您的示例中的名称不同? 【参考方案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

【讨论】:

以上是关于在一行中初始化多个私有变量的主要内容,如果未能解决你的问题,请参考以下文章

c++中关于私有静态变量的问题

如何从类内实例化的对象访问私有变量

在java中,如果没有给变量指定是公有或是私有,默认是啥?

vb.net main 不允许设置私有变量[关闭]

类的私有属性

与私有变量相关的非法表达式开头