将数据保存在.cpp和.h上的功能

问题描述:

我的问题更像是一种怀疑。将数据保存在.cpp和.h上的功能

几天前,我开始组织我的代码,但我非常喜欢它,问题是我不知道它是坏还是好,我的意思是它的工作,但我想知道如果代码变大,最终会出现问题。这我如何用我的代码做:

.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文件时唯一可以调用的函数,但这基本上是我想要的以及我正在做什么,是否有任何问题?我的意思是,我会在将来如何使用它来获得错误或任何奇怪的东西?

+1

_“我知道了‘MYDATA’指针将只是可以在这个特别的cpp文件“,_不,这是错误的。如果你在那里放置一个“静态”,那将是真的。另外,在C++中,使用具有私有数据和公共成员函数的类。 – user0042

+0

是的,这将是一个问题。不要创建返回void且不带参数的函数,也不要在文件范围创建变量。 –

+1

请不要在C++问题上使用C标签,它们是不一样的。 –

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; 
} 
+0

非常感谢您的解释。哦,关于初始化方法,这只是一个例子,我通常不会那样做,只是表达我在说什么,但是再次,谢谢 – khofez

我知道了“MYDATA”指针将只是可以在这个特定的CPP文件

那是假的。 mydata将是一个全局变量。如果另一个.cpp中有另一个mydata全局变量,它们可能会发生冲突(或者至少它们会违反一个定义规则)。对于MYDATA

使用未命名空间:

namespace { 
    myData* mydata = nullptr; 
} 

这样,mydata不会对其他翻译单元进行访问。

但是:不推荐使用全局变量。不要使用它们。他们几乎总是有替代品。

还有一个技术原因,这++只涉及到C:static initialization order fiasco

而且有设计决策背后:

+0

为什么不推荐全球变量?你能举一个简单的例子吗? – khofez

+0

谢谢你的回答! – khofez