将数据保存在.cpp上,并在 .h 上运行

Holding data on .cpp and function on .h

本文关键字:并在 运行 cpp 数据 保存 存在      更新时间:2023-10-16

我的问题更像是一个疑问。

几天前,我开始以一种我不太习惯的方式组织我的代码,但我非常喜欢它,问题是我不知道它是坏的还是好的,我的意思是它的工作,但我想知道如果代码变大它最终会成为问题。这是我使用代码的方式:

.h 文件

void init();
void someFunction1();

.cpp文件

struct myData
{
int someVar = 0;
int someVar1 = 21;
}  
myData* mydata = nullptr;
void init()
{
mydata = new myData();
mydata->someVar = 1;
}
void someFunction1()
{
mydata->someVar = mydata->someVar1;
}

我知道"mydata"指针将只在这个特定的 cpp 文件上可用,当我包含 de .h 文件时,函数是我唯一可以调用的东西,但这基本上是我想要的,它正在做的事情,这有什么问题吗?我的意思是,将来像这样使用它时会遇到错误或任何奇怪的事情吗?

mydata

也可以在其他翻译单元中使用。如果在另一个源中使用另一个具有相同名称的全局变量,则可能会产生问题。这将导致标识符冲突。

为了确保不会发生这种情况,您可以将mydata设置为静态变量:

static myData* mydata = nullptr;

或者将mydata放在未命名的命名空间中:

namespace {
myData* mydata = nullptr;
}

在这种情况下,myData不必是静态的。

现在C++通常首选第二种选择,但第一种选择将达到相同的结果,并且它本身并没有什么问题。

请注意,全局范围内的变量有一些与初始化相关的问题。例如,如果将一个全局变量初始化为在其他地方定义的另一个全局变量的值,则无法知道哪个变量将首先初始化,因此您的变量可能会使用垃圾数据进行初始化。但是,在这种情况下,您只是将其初始化为nullptr,所以没问题。然而,仍然避免全局变量是一个好习惯,因为有更好的方法可以做到这一点。您可以改为将变量包装到静态函数中,该函数返回在其中定义的静态变量:

static myData& mydata()
{
static myData mydata_instance;
return mydata_instance;
}
void init()
{
mydata().someVar = 1;
}
void someFunction1()
{
mydata().someVar = mydata().someVar1;
}

另请注意,不使用指针。mydata_instance是一个对象,而不是一个指针,这避免了必须使用new来分配内存,这意味着您不必担心调用delete稍后再次释放内存。mydata()将在第一次调用堆栈时在堆栈上创建一个myData对象,并且由于该对象是静态的,因此它将在以后每次调用mydata()时持续存在,并且每次都会返回相同的对象(静态局部变量仅初始化一次。请注意,mydata()的返回类型是一个引用(用&表示(,这意味着当您返回对象时,将返回对该对象的引用而不是副本。这使您可以直接访问函数外部的mydata_instance对象。

现在,即使上述方法有效,摆脱init()函数并重新设计myData结构以不需要它可能是一个好主意。在这种情况下,只需在结构本身中将someVar成员设置为 1。没有理由在结构中将其初始化为 0,然后必须调用init()将其设置为 1。所以总的来说:

struct myData
{
int someVar = 1;
int someVar1 = 21;
}
static myData& mydata()
{
static myData mydata_instance;
return mydata_instance;
}
void someFunction1()
{
mydata().someVar = mydata().someVar1;
}

我知道"mydata"指针将只在这个特定的 cpp 文件上可用

这是错误的。mydata将是一个全局变量。如果在另一个.cpp中有另一个mydata全局变量,它们可能会发生冲突(或者至少它们会违反一个定义规则(。

对 mydata 使用未命名的命名空间:

namespace {
myData* mydata = nullptr;
}

这样,其他翻译单元将无法访问mydata

但是:不建议使用全局变量。不要使用它们。他们几乎总是有其他选择。

有一个技术原因,仅与C++有关:静态初始化订单惨败

背后还有设计决策:

  • 为什么全球国家如此邪恶?
  • 为什么静态变量被认为是邪恶的?
  • 或者,如果您更喜欢观看视频:清洁代码会谈 - "全球状态和单例">
相关文章: