简体   繁体   English

隐藏C ++命名空间中的变量

[英]Hiding variables in a namespace C++

I have a function which aims to perform a recursive calculation. 我有一个旨在执行递归计算的函数。 If my function is programmed recursively, it takes too long to compute. 如果我的函数是递归编程的,那么计算时间太长。 Therefore, I perform memoization by storing intermediate results in an array. 因此,我通过将中间结果存储在数组中来执行memoization。

During the execution of my program, I might call the function with parameters (10,0) , (5,5) , (2,4) etc. Therefore I have a setup(double x) function which fills the entire array with the correct values. 在我的程序执行期间,我可能会使用参数(10,0)(5,5)(2,4)等调用该函数。因此,我有一个setup(double x)函数,它填充整个数组正确的价值观 I can then access any of the array values without any further calculations. 然后我可以访问任何数组值而无需进一步计算。 I only wait until x changes to call setup() again. 我只等到x改变再次调用setup()

I am wondering how I can go about implementing this in c++. 我想知道如何在c ++中实现这一点。 It doesn't make sense to me to use a class, as I would never need to create the associated object. 我使用类没有意义,因为我永远不需要创建关联的对象。 I have implemented the functions fine in a namespace, but I'm still having a problem. 我已经在命名空间中实现了很好的功能,但我仍然遇到了问题。 Even If I use an unnamed namespace, the array used by my function is visible and can be modified from outside the namespace of the function. 即使我使用未命名的命名空间,我的函数使用的数组也是可见的,并且可以从函数的命名空间外部进行修改。 If I include the header file of the namespace, that is. 如果我包含命名空间的头文件,那就是。

my code: 我的代码:

FunctionWrapper.h FunctionWrapper.h

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

      void setup(double x);
      void getValues(int n);
}

Main.cpp Main.cpp的

#include "FunctionWrapper.h"

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

If you do not want tempArray to be nameable in other source files, don't declare it in the header file. 如果您不希望tempArray在其他源文件中可以命名,请不要在头文件中声明它。 Instead, declare it in an unnamed namespace in FunctionWrapper.cpp . 相反,在FunctionWrapper.cpp中的未命名命名空间中声明它。 Then, it can only be used directly from within that source file. 然后,它只能直接在该源文件中使用。

In general, a header file should not use an unnamed namespace, as it can (and often will) cause One Definition Rule violations. 通常,头文件不应使用未命名的命名空间,因为它可能(并且经常会)导致违反一个定义规则。

Note that a better solution to your problem might, in fact, be to create a class that provides this functionality: 请注意,对您的问题更好的解决方案实际上可能是创建一个提供此功能的类:

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

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

This way, you can create an instance of this type, and all of the state is owned by that instance. 这样,您可以创建此类型的实例,并且该实例拥有所有状态。 There are many benefits to avoiding global state, including increased maintainability and testability. 避免全局状态有许多好处,包括提高可维护性和可测试性。

This does make sense as a class, and those functions as members of that class. 这作为一个类是有意义的,并且那些函数作为该类的成员。 Those functions act on that data, and you don't want anyone else to have access to that data, that sounds like a perfect use for a class. 这些函数对这些数据起作用,你不希望任何其他人访问这些数据,这听起来像是一个完美的类。 Why are you opposed to that? 你为什么反对呢?

Further to James's (as usual, excellent) answer, I'd structure things something like this: 继詹姆斯(通常,优秀)的答案之后,我会构建类似这样的东西:

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.
}

I see three options here: 我在这里看到三个选项:

  1. Put the anonymous namespace in the .cpp file where your memoized function is implemented. 将匿名命名空间放在实现memoized函数的.cpp文件中。 It will then not be able to be access from anywhere else. 然后它将无法从其他任何地方访问。
  2. Make the array containing the memoized results a static variable inside the class. 使包含memoized结果的数组成为类中的static变量。
  3. Make a class that implements operator () , and use an instance of it as your 'function'. 创建一个实现operator ()的类,并使用它的实例作为“函数”。 Then the memoization array can be a private member variable of that class. 然后memoization数组可以是该类的私有成员变量。

Option 1 is the very simplist, and it will work. 选项1非常简单,它将起作用。 Of course, if your function is ever used in a multi-threaded environment you're going to have to think about inter-thread synchronization of access to the memoized value data structure. 当然,如果您的函数曾经在多线程环境中使用过,那么您将不得不考虑访问memoized value数据结构的线程间同步。

Option 2 is a variant on option 1. Personally, I think it's the one you should go for. 选项2是选项1的变体。就个人而言,我认为这是你应该选择的。 It has the exact same drawback though. 它有完全相同的缺点。

Option 3 is, IMHO, rather fiddly. 选项3是,恕我直言,相当繁琐。 In order to have something that looks and acts like your function you will have to declare a global variable of the class. 为了拥有看起来像你的函数一样的东西,你必须声明一个类的全局变量。 But that's basically a singleton. 但这基本上是一个单身人士。 And while that might be OK in this case, it may end up being a huge pain down the road. 虽然在这种情况下可能没问题,但最终可能会成为一个巨大的痛苦。

There is one other option, but it's a huge amount of work. 还有另一种选择,但这是一项大量的工作。 It's basically making a memoizing template. 它基本上是一个记忆模板。 It would operate like option 3, but you could instantiate it for any function who's arguments satisfied the criteria for being keys of a hashmap. 它将像选项3一样运行,但您可以为任何参数满足作为hashmap键的标准的函数实例化它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM