除了main.cpp和常量标题之外,我还有一个包含两个外部文件的程序。所以共有四个文件。它们包含以下代码:
的main.cpp
#include <iostream>
using namespace std;
int ext1_func();
int ext2_func();
int main()
{
int i;
i = ext1_func();
cout << i << endl;
i = ext2_func();
cout << i << endl;
return 0;
}
ext1.cpp
#include "const.h"
int asd1=1;
int ext1_func()
{
return temp_int;
}
ext2.cpp
#include "const.h"
int asd2 = 2;
int ext2_func()
{
return temp_int;
}
const.h
#ifndef CONST_H
#define CONST_H
const int temp_int=1;
#endif
我希望如下:
1)在ext1.cpp中声明的任何变量应该只知道 到ext1.cpp中的函数,对于ext2.cpp也是如此。因此,对于“ext2_func”,“asd1”只能为“ext1_func”和“asd2”所知。
2)“exp1.cpp”和“ext2.cpp”中的函数必须能够看到“const.h”中定义的所有值
我相信我编写和附加的代码满足了这些要求,但我想问一下我是否正确地执行了此操作?是否有比我建议的更容易获得所需行为的方法?
提前致谢。
Niles的。
答案 0 :(得分:2)
在编译单元级别,您在“全局”范围内声明的符号都链接到全局变量空间。
避免这种情况的旧方法是将它们声明为静态。新方法是将它们放入匿名命名空间。它们也可以在那里声明为静态。
ext1.cpp
namespace {
/*static*/ int asd1=1;
}
标头中的const是可以的,这种方式声明的常量具有特殊的状态,实际上编译器可以在代码中替换该值。理想情况下,您至少应将它们包装在(命名)命名空间中,以避免污染全局命名空间。修改该值(使用const_cast)将是未定义的行为。
如果它是非const并且你真的想要一个全局(通常不是一个好主意),你需要在头文件中使用extern关键字,然后在一个编译单元中创建它的实例。
答案 1 :(得分:2)
我没有在main.cpp中重复ext1_func()
和ext2_func()
原型,而是为每个函数定义一个头文件,并在那里添加函数原型:
// ext1.h
#ifndef EXT1_H_INCLUDED
#define EXT1_H_INCLUDED
int ext1_func();
#endif // EXT1_H_INCLUDED
// ext2.h
#ifndef EXT2_H_INCLUDED
#define EXT2_H_INCLUDED
int ext2_func();
#endif // EXT2_H_INCLUDED
在main.cpp中:
#include "ext1.h"
#include "ext2.h"
在ext1.cpp和ext2.cpp中,将匿名命名空间用于仅对源文件本地的变量:
// ext1.cpp
#include "const.h"
#include "ext1.h"
namespace {
int asd1=1;
} // anonymous namespace
int ext1_func()
{
return temp_int;
}
类似于ext_2.cpp。
您可能还希望在头文件中使用方便的#pragma once
,而不是#ifndef/#define
包含警卫。
答案 2 :(得分:1)
您应该将ext1.cpp
和ext2.cpp
中的变量定义为静态,以防止其他文件看到它们。但是,这是一种非常糟糕的建筑方式。您应该将代码分成不同的类。有关详细信息,请参阅this。
答案 3 :(得分:1)
如果要为翻译单元(.cpp
文件)创建变量local,请将它们放入匿名命名空间中,如下所示:
namespace
{
int local_variable = 1;
}
替代方案你也可以用旧的C方式做到:
static int local_variable = 1;
此外,您不应该在头文件中定义变量,因为它将在包含此头文件的每个.cpp
模块中重复。您应该在const.h
:
extern int external_variable;
然后在相应的const.cpp
文件中定义如下:
int external_variable = 1;