2

好的,所以我有一个我的 Trig 类,我用它来存储一个静态值表,以便在我的程序中更快地执行 sin、cos 和 tan 函数。是否可以对我当前的方法进行任何评论和/或速度改进?多亏了以前的答案,我已经感觉自己对 C++ 更有能力了。

三角函数

#pragma once
#include <math.h>

class Trig
{
private:
    struct Table
    {
        static const int multiple = 10; // Accurately stores values to 1/10 of a degree
        double sin[360*multiple];
        Table();
    };
    static const Table table;
    static void shrinkRange(double*); // Shrinks degrees to range 0-359 for proper array indexing
public:
    static double sin(double);
    static double cos(double);
    static double tan(double);
};

触发.cpp

#include "Trig.h"

Trig::Table::Table() // table constructor
{
    double const PI = 3.14159265358979323;
    double const degToRad = PI/180.0;
    double const incr = 1.0/multiple;
    int index = 0;
    for (double angle = 0; index != 360*table.multiple; angle += incr)
        Table::sin[index++] = _INC_MATH::sin(angle*degToRad);
}

Trig::Table const Trig::table; // initialize static table member

void Trig::shrinkRange(double* degrees)
{
    if (*degrees >= 360)
        *degrees -= 360*( (int)*degrees/360);
    if (*degrees < 0)
        *degrees += 360*( -(int)*degrees/360 + 1);
}

double Trig::sin(double degrees)
{
    shrinkRange(&degrees);
    degrees *= table.multiple;
    return Trig::table.sin[(int)(degrees+0.5)];
}

double Trig::cos(double degrees)
{
    return Trig::sin(degrees + 90);
}

double Trig::tan(double degrees)
{
    return Trig::sin(degrees)/Trig::cos(degrees);
}
4

5 回答 5

2

C++ 不是 Java。在这种情况下,您不能调用函数或访问类的成员,因为没有类对象;您只需指定其范围即可访问静态成员:

Trig::createTable();
Trig::COS_TABLE[120];

此外(但在 Java 中也是如此),您可以通过使用动态初始化来自动确保正确的初始化。如果您真的想保留当前结构,可以添加如下内容:

bool initted = (Trig::createTable(), true);

命名空间范围内的任何位置。更惯用的方法是定义一个对象类型来包含这两个表,并使用一个初始化它们的构造函数,并声明一个静态实例:

class Trig
{
public:
    struct Tables
    {
        double sin[360];
        double cos[360];
        Tables();
    };
    static Tables const tables;
    //  ...
};

Trig::Tables const Trig::tables;

Trig::Tables::Tables()
{
    double rad = PI / 180.0;
    for ( int angle = 0; angle != 360; ++ angle ) {
        sin[angle] = std::sin( angle * rad );
        cos[angle] = std::cos( angle * rad );
    }
}

无需显式调用Trig::createTable;编译器会为您处理这个问题。

(Java 中也有类似的技术。出于某种原因,它们并不经常使用,因为上面是非常惯用的 C++。)

于 2013-08-07T09:50:13.467 回答
0

最好,使您的表(非静态)成员成为您拥有单个静态对象的类:

#include <cmath>                         // include C++ header instead of C

namespace trig {                         // use a namespace instead of a class
  const double pi = 4*std::atan2(1.,1.); // avoid pre-processor macros
  namespace details {                    // hide details in inner namespace
    struct sin_cos_tables                // class holding tables
    {
      double SIN[360];
      double COS[360];
      sin_cos_tables()                   // default constructor: set tables
      {
        const double fac = pi/180;
        for(int angle = 0; angle != 360; ++angle)
        {
          SIN[angle] = std::sin(angle*fac);
          COS[angle] = std::cos(angle*fac);
        }
      }
    };
    static sin_cos_tables TABLES;        // static object constructed at start-up
  }
  static const double*SIN_TABLE = details::TABLES.SIN;  // for your convenience
  static const double*COS_TABLE = details::TABLES.COS;  // (not really necessary)
}

int main()
{
  double x = trig::SIN_TABLE[120];
}

这样,表格会在您的其他(非静态)代码运行之前自动创建。

于 2013-08-07T10:02:22.190 回答
0
Trig::createTable();
double x = Trig::COS_Table[120];
于 2013-08-07T09:41:46.493 回答
0

::与 Java不同,静态变量需要使用 namespcae 运算符访问.

createTable()因此,要在不创建对象的情况下调用方法,请使用以下语法:

Trig::createTable();

asSIN_TABLECOS_TABLEtable 也是静态的,使用语法 as:

Trig::SIN_TABLE[120];
Trig::COS_TABLE[120];
于 2013-08-07T09:56:37.587 回答
0

为了访问静态,您需要使用:: ie

Trig::COS_TABLE

而不是Trig.COS_TABLE

但是,仅包含静态的类在 C++ 中有点奇怪。

于 2013-08-07T09:44:46.527 回答