考虑这样一个类:

class MyReferenceClass
{
public:
    MyReferenceClass();
    const double ImportantConstant1;
    const double ImportantConstant2;
    const double ImportantConstant3;
private:
    void ComputeImportantConstants(double *out_const1, double *out_const2, double *out_const3);
}

有一个例程 (ComputeImportantConstants) 在运行时计算三个常量。假设计算相当复杂,并且本质上会同时产生所有三个值。此外,结果取决于构建配置,因此不能选择对结果进行硬编码。

是否有一种明智的方法将这些计算值存储在类的相应 const double 字段中?

如果没有,你能建议一种更自然的方式在 C++ 中声明这样的类吗?

在 C# 中,我将在这里使用带有静态构造函数的静态类,但这在 C++ 中不是一个选项。我也考虑过将ImportantConstant1..3设为非常量字段或函数调用,但两者似乎都较差。

我发现初始化 const 字段的唯一方法是 使用初始化列表, ,但似乎不可能在这样的列表中传递多输出计算的结果。

有帮助吗?

解决方案

为什么你不能这样做:

MyReferenceClass ComputeImportantConstants(){
    //stuff to compute
    return MyReferenceClass( const1, const2, const3 );
}

MyReferenceClass{
public:
    MyReferenceClass(double _1, double _2, double _3) 
        : m_Const1(_1),
        m_Const2(_2),
        m_Const3(_3){}

    double getImportantConst1() const { return m_Const1; }
    double getImportantConst2() const { return m_Const2; }
    double getImportantConst3() const { return m_Const3; }
private:
    const double m_Const1,
                 m_Const2,
                 m_Const3;
};
.

类似,并将计算功能变成工厂函数?

其他提示

首先 - 您可以做邪恶:在ComputeImportantantantantants()中抛弃Const并将值放在那里。不过,因为那么你骗了编译器,它会试图找到最大的回报。

第二:

这样做:

class A
private:
  double important1;
  double important2;
  double important3;
  A() { ComputeImportantConstants(); } //no need for parameters, it accesses the members
  void ComputeImportantConstants();
public:
  inline double GetImportant1() { return important1; }
  inline double GetImportant2() { return important2; }
  inline double GetImportant3() { return important3; }
};
.

你仍然可以通过制作某种单身偶数来改善这个课程(因为你希望计算只做一次)。

你可以移动 const 字段传递给基类,然后传递包装类来初始化它们:

class MyBase
{
protected:
    const double ImportantConstant1;
    const double ImportantConstant2;
    const double ImportantConstant3;

    struct Initializer
    {
        double d1;
        double d2;
        double d3;
    };

    MyBase(Initializer const& i):
        ImportantConstant1(i.d1),ImportantConstant2(i.d2),ImportantConstant3(i.d3)
    {}
};

class MyReferenceClass:
    private MyBase
{
public:
    using MyBase::ImportantConstant1;
    using MyBase::ImportantConstant2;
    using MyBase::ImportantConstant3;
    MyReferenceClass():
        MyBase(makeInitializer())
    {}

private:
    MyBase::Initializer makeInitializer()
    {
        MyBase::Initializer i;
        ComputeImportantConstants(&i.d1,&i.d2,&i.d3);
        return i;
    }

    void ComputeImportantConstants(double *out_const1, double *out_const2, double *out_const3);
};

初始化Const字段的唯一方法是使用初始化程序列表,但似乎在这样的列表中似乎无法通过多输出计算结果。

这是真的;但是,您可以初始化单个成员 - 这是常量的结构。见下文。

我还考虑制作重要组合第1 angStant1..3非Const字段或函数调用,但两者似乎都是低劣的。

我不认为气体功能会劣等。编译器很可能蕴含它们。考虑一下:

class MyReferenceClass
{
public:
    MyReferenceClass() : m_constants( ComputeImportantConstants() ) { }

    inline double ImportantConstant1() const { return m_constants.c1; }
    inline double ImportantConstant2() const { return m_constants.c2; }
    inline double ImportantConstant3() const { return m_constants.c3; }

private:
    struct Constants {
        Constants( double c1_, double c2_, double c3_ ) : c1( c1_ ), c2( c2_ ), c3( c3_ ) { }

        const double c1;
        const double c2;
        const double c3;
    };

    Constants ComputeImportantConstants() {
        return Constants( 1.0, 2.0, 3.0 );
    }

    const Constants m_constants;
};
.

由于生成的icOdeTagcode以及所有字段都是常量,因此无法通过其他成员方法更改值 - 只是在您在问题中绘制的代码中。初始化可以是 在这里使用,因为我们初始化单个值:结构。

访问常量是(最有可能的)与以前一样有效:建议在内联函数,编译器很可能会这样做,因为getters的小程度如何。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top