如何在 C++ 中跨多个源文件共享一个变量?
How to share a variable across multiple source files in C++?
我的目标总结
我想在 C++[=107= 中的多个 .cpp
文件之间共享声明的 class 的 全局实例 ].
解释
如果想走得快,可以在期望值之后跳转。
我知道很多人说我不应该使用全局变量,原因太多...阅读我的解释明白我为什么想要它们。
第 1 步:
我正在做一个 C++ 程序,在头文件中定义了 class。
(class的函数是在cpp文件中声明的。)
为了解释它,我将使用过度简化的假设 代码。 (不是真实的。)
简化假设的 Class.h
代码:
class Class {
public:
Class(intx,int y); //Does a lot of things
int OP1(int x); //Dummy operation
int OP2(int x); //Dummy operation
private:
type ManyVars;
}
简化假设 main.cpp
的代码
#include "Class.h"
Class Member(140,360); //Declares it with parameters
bool Func1(int x) { //Dummy function
int y = Member.OP2(x);
return x > Member.OP1(y);
}
bool Func2(int x) { //Dummy function
int y = Member.OP2(x) * x;
return x > Member.OP1(y) +1;
}
int main() {
int x;
std::cin >> x;
y = Func2(x);
z = Func1(y * x / 5);
return Func2(z) + x / y;
}
就我而言,一切正常,但是 main.cpp
中的代码非常大 因为我有超过 16 个函数,包括 2 个大函数!
(为简单起见,我在示例中只显示了两个函数。)
第 2 步:
为了让代码更容易阅读,我将小函数移到了另外两个文件Funcs.cpp
和Funcs.h
,就像一个库.
然后我将大函数移动到一个新的 .cpp
文件中,每个函数都包含在另一个头文件中。
(隐藏在示例中,因为它类似于 Funcs.cpp
。)
所以,现在假设的 main.cpp
看起来像这样:
#include "Class.h"
#include "Funcs.h"
Class Member(140,360);
int main() {
int x;
std::cin >> x;
int y = Func2(x);
int z = Func1(y * x / 5);
return Func2(z) + x / y;
}
假设的 Funcs.cpp
看起来像这样:
#include "Class.h"
#include "Funcs.h"
bool Func1(int x) {
int y = Member.OP2(x);
return x > Member.OP1(y);
}
bool Func2(int x) {
int y = Member.OP2(x) * x;
return x > Member.OP1(y) +1;
}
现在出现一个问题:Member
仅 定义在 main.cpp
但我也需要它 Funcs.cpp
(还有其他函数文件).
第 3 步:
我尝试为每个函数添加另一个 Class
类型的输入值,并在使用时将 Member
放入其中。它 有效,但功能看起来很糟糕 ! 我不希望每个函数都有额外的参数!所以我暂时将代码恢复到步骤 1。
预期
我想要的是在它们之间共享同一个实例的任何方式。 基本上是一个全局变量。
我想保持相同的功能。 int y = Member.OP2(x)
不能更改 而每个文件的开头可以更改.
我希望能够声明多个这样的 Member
s(我不会,但必须可以做到)。
有谁知道这样共享实例的方法吗?
有什么不明白的地方请告诉我。
Member
是一个全局变量。使用您将用于任何全局变量的常用技术共享它,在头文件中声明它并在源文件中定义它(一次)。
在头文件中(比如 Class.h)
extern Class Member;
在main.cpp
Class Member(140,360);
就是这样。
另一种使用全局变量的方法是利用 单例模式 通过在静态存储中存储 Class 的唯一实例(首先构造使用成语).
有个question that explains the difference between this and john's answer (c.f. the C++ FAQ that addresses what is initialisation order fiasco and how does this approach avoid it).
template<int x, int y>
class Class
{
public:
static Class & get_instance()
{
static Class instance; // <- called only once!
return instance;
}
Class(const Class &) = delete;
Class & operator=(const Class &) = delete;
bool OP1(int a)
{
return a > x;
}
bool OP2(int b)
{
return b > y;
}
private:
Class() = default;
~Class() = default;
};
然后,您可以通过get_instance()
方法获取对实例的引用,如
auto& Member = Class<140,360>::get_instance();
我的目标总结
我想在 C++[=107= 中的多个 .cpp
文件之间共享声明的 class 的 全局实例 ].
解释
如果想走得快,可以在期望值之后跳转。
我知道很多人说我不应该使用全局变量,原因太多...阅读我的解释明白我为什么想要它们。
第 1 步:
我正在做一个 C++ 程序,在头文件中定义了 class。
(class的函数是在cpp文件中声明的。)
为了解释它,我将使用过度简化的假设 代码。 (不是真实的。)
简化假设的 Class.h
代码:
class Class {
public:
Class(intx,int y); //Does a lot of things
int OP1(int x); //Dummy operation
int OP2(int x); //Dummy operation
private:
type ManyVars;
}
简化假设 main.cpp
的代码
#include "Class.h"
Class Member(140,360); //Declares it with parameters
bool Func1(int x) { //Dummy function
int y = Member.OP2(x);
return x > Member.OP1(y);
}
bool Func2(int x) { //Dummy function
int y = Member.OP2(x) * x;
return x > Member.OP1(y) +1;
}
int main() {
int x;
std::cin >> x;
y = Func2(x);
z = Func1(y * x / 5);
return Func2(z) + x / y;
}
就我而言,一切正常,但是 main.cpp
中的代码非常大 因为我有超过 16 个函数,包括 2 个大函数!
(为简单起见,我在示例中只显示了两个函数。)
第 2 步:
为了让代码更容易阅读,我将小函数移到了另外两个文件Funcs.cpp
和Funcs.h
,就像一个库.
然后我将大函数移动到一个新的 .cpp
文件中,每个函数都包含在另一个头文件中。
(隐藏在示例中,因为它类似于 Funcs.cpp
。)
所以,现在假设的 main.cpp
看起来像这样:
#include "Class.h"
#include "Funcs.h"
Class Member(140,360);
int main() {
int x;
std::cin >> x;
int y = Func2(x);
int z = Func1(y * x / 5);
return Func2(z) + x / y;
}
假设的 Funcs.cpp
看起来像这样:
#include "Class.h"
#include "Funcs.h"
bool Func1(int x) {
int y = Member.OP2(x);
return x > Member.OP1(y);
}
bool Func2(int x) {
int y = Member.OP2(x) * x;
return x > Member.OP1(y) +1;
}
现在出现一个问题:Member
仅 定义在 main.cpp
但我也需要它 Funcs.cpp
(还有其他函数文件).
第 3 步:
我尝试为每个函数添加另一个 Class
类型的输入值,并在使用时将 Member
放入其中。它 有效,但功能看起来很糟糕 ! 我不希望每个函数都有额外的参数!所以我暂时将代码恢复到步骤 1。
预期
我想要的是在它们之间共享同一个实例的任何方式。 基本上是一个全局变量。
我想保持相同的功能。 int y = Member.OP2(x)
不能更改 而每个文件的开头可以更改.
我希望能够声明多个这样的 Member
s(我不会,但必须可以做到)。
有谁知道这样共享实例的方法吗?
有什么不明白的地方请告诉我。
Member
是一个全局变量。使用您将用于任何全局变量的常用技术共享它,在头文件中声明它并在源文件中定义它(一次)。
在头文件中(比如 Class.h)
extern Class Member;
在main.cpp
Class Member(140,360);
就是这样。
另一种使用全局变量的方法是利用 单例模式 通过在静态存储中存储 Class 的唯一实例(首先构造使用成语).
有个question that explains the difference between this and john's answer (c.f. the C++ FAQ that addresses what is initialisation order fiasco and how does this approach avoid it).
template<int x, int y>
class Class
{
public:
static Class & get_instance()
{
static Class instance; // <- called only once!
return instance;
}
Class(const Class &) = delete;
Class & operator=(const Class &) = delete;
bool OP1(int a)
{
return a > x;
}
bool OP2(int b)
{
return b > y;
}
private:
Class() = default;
~Class() = default;
};
然后,您可以通过get_instance()
方法获取对实例的引用,如
auto& Member = Class<140,360>::get_instance();