C++ 在.cpp上保存数据,在.h上保存函数
我的问题更像是一个疑问 几天前,我开始用一种我不太习惯的方式组织我的代码,但我非常喜欢它,问题是我不知道它是好是坏,我是说它可以工作,但我想知道代码是否会变大,最终会成为问题。这是我如何使用代码的: .h文件C++ 在.cpp上保存数据,在.h上保存函数,c++,struct,C++,Struct,我的问题更像是一个疑问 几天前,我开始用一种我不太习惯的方式组织我的代码,但我非常喜欢它,问题是我不知道它是好是坏,我是说它可以工作,但我想知道代码是否会变大,最终会成为问题。这是我如何使用代码的: .h文件 void init(); void someFunction1(); .cpp文件 struct myData { int someVar = 0; int someVar1 = 21; } myData* mydata = nullptr; void init()
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”指针将仅在这个特定的cpp文件上可用
那是假的mydata
将是一个全局变量。如果在另一个.cpp中有另一个mydata
全局变量,它们可能会发生冲突(或者至少会违反一个定义规则)
为mydata使用未命名的命名空间:
namespace {
myData* mydata = nullptr;
}
这样,mydata
就不会被其他翻译单元访问
但是:不建议使用全局变量。不要使用它们。他们几乎总是有其他选择
<> P>有一个技术原因,它只与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\u实例
是一个对象,而不是指针,这避免了必须使用new
来分配内存,这意味着您不必担心调用delete
以后再次释放内存mydata()
将在第一次调用时在堆栈上创建一个mydata
对象,由于该对象是静态的,它将在以后每次调用mydata()
时保持不变,并且每次都会返回相同的对象(静态局部变量只初始化一次。)请注意mydata()的返回类型
是一个引用(用&
表示),这意味着当您返回对象时,将返回对该对象的引用,而不是副本。这使您可以直接访问函数外部的mydata\u实例
对象
现在,尽管上面的方法可以工作,但最好去掉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文件上可用,“不,那是错误的。如果您在那里放置一个
static
,则为真。还有C++使用一个带有私有数据和公共成员函数的类。是的,这将是一个问题。不要创建返回空洞的函数,不带参数,不要在文件范围内创建变量。请不要在C++问题上使用C标记,它们不一样。你到底在做什么?你用这种代码干什么?当函数听起来很像方法时,为什么不使用适当的类呢?我的意思是,我希望这是一个在实际代码中看起来不同的示例,没有任何名称空间之外的像init这样的泛型名称,也没有在cpp之外甚至没有提到的全局变量。@khofez如果您在另一个.cpp
文件中放置extern myData*myData代码>声明,是的。为什么不推荐全局变量?你能举个简单的例子吗?谢谢你的回答!非常感谢你的解释。哦,关于init方法,这只是一个例子,我通常不会这样做,它只是表达我所说的,但再次感谢你