所以,我正在研究一个项目,并决定将代码分成多个文件,因为它太大了。但是,有一个编译错误。我设法在这个简单的情况下重新创建错误:
//main.cpp
#include<iostream>
#include "classa.h"
using namespace std;
int main()
{
return 0;
}
主要做什么它只包括classa.h
//classa.h
#ifndef CLASSA_H_INCLUDED
#define CLASSA_H_INCLUDED
#include<vector>
using namespace std;
vector<int> primes= {1,2,3,5,7,11,13,17,19};
class classa
{
private:
int a;
public:
int getA();
void setA(int newA);
};
#endif //CLASSA_H_INCLUDED
发生错误甚至不需要这门课程。但是,我想在classa.cpp
中找到一些东西//classa.cpp
#include "classa.h"
using namespace std;
int classa::getA()
{
return a;
}
void classa::setA(int newA)
{
a=newA;
}
它给了我以下错误:
obj\Debug\sources\main.o:main.cpp:(.bss+0x0): multiple definition of `primes'
obj\Debug\sources\classa.o:classa.cpp:(.bss+0x0): first defined here
问题在于,与我的项目不同,我不能使用某种常量或全局变量的定义,因为它们是可以被不同类修改的东西。
答案 0 :(得分:4)
将素数设为extern
变量,并在classa.h
标题中声明,但仅在classa.cpp
中定义一次。
目前,正如您的编译器告诉您的那样,素数在main.cpp
和classa.cpp
中存在两次。请注意,#include
仅仅是文字替换。
classa.h:
extern std::vector<int> const primes;
classa.cpp:
std::vector<int> const primes = {1,2,3,5,7,11,13,17,19};
详细了解存储类说明符here。
答案 1 :(得分:0)
如果整体上有.cpp文件 - 则分成
是有意义的进入.h文件:
extern std::vector<int> primes;
进入.cpp文件:
using namespace std;
vector<int> const primes = {1,2,3,5,7,11,13,17,19};
“using namespace std”可能会导致第三方库之间发生冲突,但这种情况很少发生 - 我希望尽可能使用“using namespace std”。但是如果存在冲突 - 那么您可能希望将“using namespace std”本地化为您自己的.cpp文件。 (你控制那个文件的#include)。
但有时你可能根本没有.cpp文件(例如只有本地内联函数或模板类) - 然后你可以像这样初始化vector:
__declspec(selectany) std::vector<int> primes = {1,2,3,5,7,11,13,17,19};
这将指示链接器仅拾取一个副本(其中一些副本),并丢弃其他所有副本。如果你想#ifdef一些初始化,这不会很好,但无论如何这不是正常的用例。
我不喜欢永远使用const,因为在2-3级转换之后获得const是总是痛苦的。我在函数注释中写入什么是输入/什么是输出以及什么不应该被修改。 (因为那个可以改变迭代)