C++中的公共块等价

Common block equivalent in C++

本文关键字:C++      更新时间:2023-10-16

我正在尝试将一个旧的Fortran 77代码转换为C++,并且大多数变量都在公共块中声明,例如:

COMMON/BLK1/Gw(200),Eta(4096),t(4096),Phi(200),w(200)
COMMON/BLK2/g,dw,Vel,M,dt,N,Ioutp1,Ioutp2
COMMON/BLK3/Hs,Std,E,Hs1,Tdt

据我所知,公共块只是用来让不同子程序中的变量在整个程序中都可以访问。因此,在C++程序中,我是否能够使用变量(在main之外)创建结构,并以这种方式将变量作为结构的成员进行调用?

根据我在本页中对COMMON的理解,C++的等效方法是创建一个名为common.h(包含保护)的文件,其中包含:

 namespace BLK1
 {
      int const Gw = 200;
      int const Eta = 4096;
      int const t = 4096;
      int const Phi = 200;
      int const w = 200;
 }
 namespace BLK2
 {
      extern int g, dw, Vel, M, dt, N, Ioutp1, Ioutp2;
 }
 namespace BLK3
 {
      extern int Hs, Std, E, Hs1, Tdt;
 }

此外,在项目中的一个.cpp文件中,您需要为任何非常量提供定义,例如在foo.cpp:中

 #include "common.h"
 namespace BLK2
 {
      int g, dw, Vel, M, dt, N, Ioutp1, Ioutp2;
 }
 namespace BLK3
 {
      int Hs, Std, E, Hs1, Tdt;    // initialized to 0 by default
 }

您可能希望使用与int不同的类型,例如unsigned long。我假设初始化的值是const;如果不是,则将int const更改为extern int并移除初始值设定项。初始值设定项必须进入.cpp文件中的定义。

避免在头中声明非常量、非外部变量的错误;如果标头包含在两个不同的单元中,则会导致未定义的行为。

例如,您可以通过编写BLK1::Eta来访问这些变量。

正如您推测的那样,使用struct而不是命名空间可能会被认为更整洁,尽管您仍然需要创建结构的实例,该实例在标头中声明为extern,并在一个.cpp文件中定义;如果你是C++11之前的版本,那么提供初始化程序就更麻烦了。

(当然,更好的方法是重构代码,使其不使用全局变量。但作为直接翻译的第一步,这可能很有用)。

具有相同名称的公共块在内存中相互重叠。你可以分配一块内存,并对其进行类型转换指针。另一种选择是在联合中声明它们。这就是为什么发明了工会。当然,一旦建立了联合,就可以在其他模块中使用extern。

将以下内容放入一个公共标头中,并将其实例放入模块1中。添加一个extern,以便在模块2中可以看到它。

union blk1
{
    struct module_1_view
    {
        double gw(200);
        double eta(4096);
        double t(4096);
        double phi(200);
        double w(200);
    } 
    struct module_2_view
    {
        double parameters(8592);   // 200 + 4096 + 4096 + 200
        double w_status(200);
    } 
}

想象一下,模块1负责将文件中的某组double加载到module_1_view中的变量中。一旦加载并验证了这些参数,就会调用模块2,该模块从模块2视图访问参数。除了w_status之外,几乎所有这些都是通过parameters变量访问的,w_statu斯实际上是200个指示参数成功或验证的指标。

关键是模块1和2访问相同的内存块(因此是并集),并且它们使用自己的一组变量名。

我不能直接与Fortran对话,但如果您想在整个c/c++程序中访问一个变量,extern就是您要查找的关键字。

Extern是一种C风格的数据共享方式。C++会把你推向OO设计,其中一个与许多对象紧密耦合的变量不是好的OO。

如果您试图在遗留代码之上进行C++操作,有时静态方法(传递给C++类的指针)可以充当包装器。这里有一个简单的例子:

extern int _magicVariable;
static void call( void* klass )
{
  ((MyClass*)klass)->functionCall( _magicVariable );
}

在MyClass中,您需要将void call(void*)命名为好友。现在,遗留代码可以使用指向类的指针调用(void*),将_magicVariable传递到OO设计中。从那里开始,c++将完成它的任务。

底线是你有很多方法来完成任务,试着根据你想要的代码结构做有意义的事情。

相关文章:
  • 没有找到相关文章