【问题标题】:A const big array needs to be initialized需要初始化一个 const 大数组
【发布时间】:2014-01-21 02:48:19
【问题描述】:

我的班级中有一个doubles 的静态数组,我希望它是const,但我需要以某种方式对其进行初始化。确保构造函数返回后它将是“const”的最佳方法是什么?

class DFTDriver {        
public:
    static const size_t tblsize = 16384;
    DFTDriver() {
        for (unsigned i = 0; i != tblsize; ++i) {
            sintbl[i] = std::sin(i * TAU / tblsize);
            costbl[i] = std::cos(i * TAU / tblsize);
        }
    }
private:
    static double sintbl[tblsize];
    static double costbl[tblsize];
};

我知道我需要一个计算来初始化它们,所以要求它们是const 是不合理的;但是,该数组显然是“语义上的 const”。

我看到here 如果我正在初始化一个向量而不是一个数组,就会有一个答案。是否可以使用类似的方法?

我希望能够在不诉诸新的 C++11 结构的情况下做到这一点,但如果不可能,那就让 C++11 来做吧。

【问题讨论】:

  • 如果它是静态的......为什么要在构造函数中初始化它(即非静态函数)
  • 您可以像定义中的任何其他数组一样使用初始化列表。不过,您必须计算这些值。
  • 没错,我应该在 main() 函数中初始化它,或者类似的东西。无论如何,我的问题仍然存在,如何在“初始化”之后使它们成为“常量”(这看起来像一个分配,但应该是一个初始化)?
  • 初始化后不要将其设为 const 。您将其声明为 const ,这意味着您决定其值的唯一机会是在初始化时。顺便说一句, main 是错误的地方。 P.S:我建议您使用矢量并遵循您链接的问题中的技术。

标签: c++ arrays static initialization


【解决方案1】:

编写程序来生成表格

FILE * file = fopen( "sintbl.cpp", "w" );
fprintf( file, "const double DFTDriver::sintbl[] = {\n" );
for (unsigned i = 0; i != tblsize; ++i) {
    fprint( file, "  %f , \n", std::sin(i * TAU / tblsize) );
}
fprintf( file, "};\n" );
fclose( file );

然后编译生成的文件并链接到你的程序中。

【讨论】:

【解决方案2】:

我知道这里的很多人都喜欢否决我的回答,但我希望他们在这样做之前会考虑一下。

也许这个问题正是应该使用简单强制转换的情况。数据字段应声明为 const。这将保证它不会在某处被意外更改。您应该在初始化函数中分配非常量指针并将其指向您的数据。做演员,添加详细的评论并解释你为什么这样做,你会没事的。优点:

  1. 代码绝对清晰;
  2. 它可以在任何平台/编译器上顺利运行;
  3. 铸造只在一个不太可能改变的地方。

附言我建议添加您的类的静态实例并使您的 ctor 私有。这将保证 ctor 会在一开始就被调用:

class DFTDriver
{        
private:

    DFTDriver() { .... }

    static DTFDriver inst;

    static double sintbl[tblsize];
    static double costbl[tblsize];
};

生成源代码的另一个答案也很有意义,尽管代码会更难维护。

【讨论】:

    【解决方案3】:

    这应该可以工作

    class DFTDriver {   
        template<class ElementType, size_t size>
        struct Buffer
        {
            Buffer(ElementType(*initializer)(size_t i)) {
                for(size_t i = 0; i < size; ++i) {
                    data[i] = initializer(i);
                }
            }
            const ElementType operator[](size_t i) const {return data[i];}
            ElementType& operator[](size_t i) {return data[i];}
            ElementType data[size];
        };
        double initSinbl(size_t i) { 
             return std::sin(i * TAU / tblsize);
        }
        double initCosbl(size_t i) {
            return std::cos(i * TAU / tblsize);
        }
    public:
        static const size_t tblsize = 16384;
    private:
        //initSinbl and initCosbl can be replaced with lambdas in c++11
        static const Buffer<double, tblsize> sintbl(&initSinbl);
        static const Buffer<double, tblsize> costbl(&initCosbl);
    };
    

    【讨论】:

      猜你喜欢
      • 2016-04-14
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-04
      • 1970-01-01
      相关资源
      最近更新 更多