Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在命名空间C+中隐藏变量+;_C++_Namespaces - Fatal编程技术网

C++ 在命名空间C+中隐藏变量+;

C++ 在命名空间C+中隐藏变量+;,c++,namespaces,C++,Namespaces,我有一个函数,旨在执行递归计算。如果我的函数是递归编程的,那么计算起来会花费太长时间。因此,我通过将中间结果存储在数组中来执行记忆 在程序执行期间,我可能会使用参数(10,0)、(5,5)、(2,4)等调用该函数。因此,我有一个设置(双x)函数,它用正确的值填充整个数组。然后,我可以访问任何数组值,而无需进一步计算。我只需等到x发生更改,即可再次调用setup() 我想知道我如何在C++中实现这个。使用类对我来说没有意义,因为我永远不需要创建关联的对象。我已经在名称空间中很好地实现了这些函数,但

我有一个函数,旨在执行递归计算。如果我的函数是递归编程的,那么计算起来会花费太长时间。因此,我通过将中间结果存储在数组中来执行记忆

在程序执行期间,我可能会使用参数
(10,0)
(5,5)
(2,4)
等调用该函数。因此,我有一个
设置(双x)
函数,它用正确的值填充整个数组。然后,我可以访问任何数组值,而无需进一步计算。我只需等到
x
发生更改,即可再次调用
setup()


我想知道我如何在C++中实现这个。使用类对我来说没有意义,因为我永远不需要创建关联的对象。我已经在名称空间中很好地实现了这些函数,但仍然存在一个问题。即使使用未命名的命名空间,函数使用的数组也是可见的,并且可以从函数的命名空间之外进行修改。如果我包括名称空间的头文件,也就是说

我的代码:

FunctionWrapper.h

namespace FunctionWrapper{
      namespace{
            double tempArray[10][10];
      }

      void setup(double x);
      void getValues(int n);
}
Main.cpp

#include "FunctionWrapper.h"

int main(){
   FunctionWrapper::tempArray[0][0] = 5; //Works
}

如果不想在其他源文件中命名
tempArray
,请不要在头文件中声明它。相反,在FunctionWrapper.cpp中的未命名命名空间中声明它。然后,它只能直接从源文件中使用

通常,头文件不应使用未命名的命名空间,因为它可能(而且通常会)导致违反一个定义规则

请注意,事实上,更好的解决方案可能是创建一个提供此功能的类:

class ValueGetter
{
public:
    ValueGetter(double x);
    void GetValues(int n);

private:
    double cache[10][10];
};

这样,您就可以创建这种类型的实例,并且所有状态都属于该实例。避免全局状态有很多好处,包括增加了可维护性和可测试性。

这对于类来说是有意义的,并且这些函数作为该类的成员。这些函数作用于该数据,您不希望其他任何人访问该数据,这听起来像是类的完美用途。你为什么反对这一点?

继詹姆斯(和往常一样,非常好)的回答之后,我会这样安排:

namespace {
class value_cache { 
     double temp_array[10][10];
     int x;
     void setup(double x);
     void internal_getValues(int); // same as your current GetValues
public:
     void getValues(int n) { 
         if (x != n) 
            setup(x=n);            
         internal_getValues(n);
     }
};
}

double function(int x, int y) {
     static value_cache c;

     c.getValues(x); 
     // probably more stuff here.
}

我在这里看到三种选择:

  • 将匿名名称空间放在实现记忆化函数的
    .cpp
    文件中。它将无法从其他任何地方访问
  • 将包含已记录结果的数组设置为类内的
    静态
    变量
  • 创建一个实现
    操作符()
    的类,并将其实例用作“函数”。然后,memorization数组可以是该类的私有成员变量
  • 选项1是最简单的,它会起作用。当然,如果您的函数曾经在多线程环境中使用过,那么您将不得不考虑访问记忆值数据结构的线程间同步

    选项2是选项1的变体。就我个人而言,我认为这是你应该选择的。但它也有完全相同的缺点

    依我看,方案3相当棘手。为了使某个函数的外观和行为与您的函数相似,您必须声明该类的全局变量。但这基本上是单身。在这种情况下,这可能没问题,但最终可能会成为一个巨大的痛苦


    还有一个选择,但这是一个巨大的工作量。它基本上是制作一个记忆模板。它的运行方式与选项3类似,但您可以为任何参数满足哈希映射键条件的函数实例化它。

    “即使我使用未命名的命名空间,函数使用的数组也是可见的,并且可以从函数的命名空间之外进行修改。”这不是真的。在程序中的每个翻译单元中都可以看到具有相同名称的不同数组,但函数使用的数组只能从包含函数的翻译单元中修改。头文件中的未命名名称空间(几乎?)永远不会有用。