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

时间:2017-07-25 23:39:44

标签: c++ struct

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

几天前我开始以一种我不习惯的方式组织我的代码,但我很喜欢它,问题是我不知道它是坏还是好,我的意思是它的工作,但我想知道是否代码越来越大,最终会出现问题。这就是我如何处理我的代码:

.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文件时,函数是我唯一可以调用的函数,但这基本上就是我想要的和它我正在做的事情,就是任何问题都在那?我的意思是,将来会像这样使用它来获取错误或任何奇怪的内容吗?

2 个答案:

答案 0 :(得分:1)

  

我知道" mydata"指针将在此特定cpp文件上可用

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

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

namespace {
    myData* mydata = nullptr;
}

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

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

有一个技术原因,仅与C ++相关:static initialization order fiasco

背后有设计决策:

答案 1 :(得分:1)

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