在构造函数中初始化多个相关const属性的最简单方法?

时间:2013-03-20 22:07:45

标签: c++ constructor const

当C ++类的多个const属性依赖于某些中间计算时,初始化它们的最简单方法是什么?

例如,如何更正下面类的构造函数?

class MyClass {
public:
    const int a;
    const int b;

    MyClass() {
        int relatedVariable = rand() % 250;
        a = relatedVariable % 100;
        b = abs(relatedVariable - 150);
    }
};

8 个答案:

答案 0 :(得分:11)

使用C ++ 11,您只需使用委托构造函数:

class MyClass
{
public:
    const int a;
    const int b;

private:
    MyClass( int relatedVariable )
      : a( relatedVariable % 100 ),
        b( abs( relatedVariable - 150 ) ) {}

public:
    MyClass() : MyClass( rand() % 250 ) {}
};

答案 1 :(得分:6)

这是使用委托构造函数的迂回解决方案:

class MyClass
{
    MyClass(int aa, int bb) : a(aa), b(bb) { }

    static MyClass Maker() { int x = /* ... */; return MyClass(x * 2, x * 3); }

    int const a;
    int const b;

public:
    MyClass(MyClass const &) = default;
    MyClass() : MyClass(Maker()) { }
};

答案 2 :(得分:2)

你可以做这样的事情 - 不漂亮,但应该做的伎俩:

class MyClass {
public:
    const int a;
    const int b;
    static int relatedVariable;
    MyClass() :
        a(setRand()),
        b(relatedVariable)  {}
    static const int setRand()
    {
        relatedVariable = rand() % 250;
        return relatedVariable;
    }
};
int MyClass::relatedVariable = 0;

答案 3 :(得分:2)

对于我们这些碰巧喜欢不那么先进的编码的人来说,这将是工作

class MyClass {
public:

    int iamStupid;      /* K.I.S.S. */

    const int a;
    const int b;

    MyClass()
      : iamStupid(rand() % 250)
      , a(iamStupid % 150)
      , b(abs(iamStupid - 150))
    {}
};

附加成员会产生不必要的开销 - 这对于手头的任务可能有用也可能没有意义。 OTOH,代码很简单。

请务必在 iamStupida之前声明b ! (见评论)

答案 4 :(得分:2)

如果你遇到一个不支持委托构造函数的古老编译器,这里适用于旧语言版本的方法相同:

class MyClassBase {
public:
    const int a;
    const int b;
    MyClassBase(int a, int b) : a(a), b(b) {}
};

class MyClass : public MyClassBase {
    static MyClassBase Maker() {
        int x = rand() % 250;
        return MyClassBase(x % 100, abs(x - 150));
    }
public:
    using MyClassBase::a;
    using MyClassBase::b;

    MyClass() : MyClassBase(Maker()) { }
};

答案 5 :(得分:1)

介绍一个进行计算的中间类:

class ConstCalc {

   public:
    ConstCalc(int related) : rv(related){}

    int a() const { return rv % 100; } 
    int b() const { return abs( rv - 150 ) ; } 

   private:
    const int rv;
};

class MyClass {
public:
    const int a;
    const int b;

    MyClass( const ConstCalc c ) : a( c.a() ), b( c.b() ) {
    }
};

答案 6 :(得分:1)

Const是类的用户和实现者之间的契约。它表明类用户不应该修改成员变量,因此提供了不可变对象设计。构造函数可以以其他方式初始化该状态。也就是说,将它们隐藏在私有访问限定符后面并提供允许只读的访问器可能更好。暂时删除const-ness的正确方法是使用const_cast<>。

class MyClass {
public:
   const int a;
   const int b;

MyClass() : a(0), b(0) {
    int relatedVariable = rand() % 250;
    const_cast<int&>(a) = relatedVariable % 100;
    const_cast<int&>(b) = abs(relatedVariable - 150);
}

};

答案 7 :(得分:-1)

您可以将ab设为私有,并提供getter以从课堂外访问其值。

class MyClass
{
private:
    int a, b; // private
public:
    int getA() { return a; }
    int getB() { return b; }

    MyClass()
    {
        int relatedVariable = rand() % 250;
        a = relatedVariable % 100;
        b = abs(relatedVariable - 150);
    }
};

或者,您可以使用子对象初始值设定项并以某种方式缓存随机数。打开优化甚至可能会删除生成的程序文本中的临时变量。

class MyClass
{
private:
    int temp; // this is a workaround
public:
    const int a;
    const int b;

    MyClass() : temp(rand() % 250), a(temp % 100), b(abs(temp - 150)) {}
};

Remember that subobject construction happens in the order that members are declared in the class, and that the order of subobjects in the initialization list is ignored.

或者,您可以保持懒惰,只存储初始随机数,并根据需要生成a, b