链接器将代码分成.h和.cpp文件时出错

ran*_*ght 1 c++ linker-errors

我有一个实现在c ++中打印出枚举值

如果我将所有代码放在.h文件中,一切都很顺利.如果我将函数实现分离到.cpp文件中,我会收到链接器错误.

这是我的主文件

#include <iostream>
#include <vector>
#include "Day.h"
using namespace std;

int main(){
    initializeDayNames();
    Day a = Clubs;
    cout << a;
}
Run Code Online (Sandbox Code Playgroud)

这是.h文件

#ifndef __Day__
#define __Day__

#include <iostream>
#include <vector>
#include <string>
using namespace std;

enum Day {Clubs, Hearts, Diamonds, Spades} ;

vector<string> DayNames = vector<string>();

ostream & operator<<(ostream & out, Day cs);

void initializeDayNames();

#endif
Run Code Online (Sandbox Code Playgroud)

和.cpp文件

#include <iostream>
#include "Day.h"
#include<string>
#include<vector>
using namespace std;

void initializeDayNames(){
    DayNames.push_back("Clubs");
    DayNames.push_back("Hearts");
    DayNames.push_back("Diamonds");
    DayNames.push_back("Spades");
}


ostream & operator<<(ostream & out, Day cs){
    out << DayNames[cs];
    return out;
}
Run Code Online (Sandbox Code Playgroud)

我在这做错了什么

具体错误是

Error   1   error LNK2005: "class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > DayNames" (?DayNames@@3V?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@A) already defined in Day.obj main.obj
Run Code Online (Sandbox Code Playgroud)

和

Error   2 fatal error LNK1169: one or more multiply defined symbols found   
Run Code Online (Sandbox Code Playgroud)

Xzh*_*hsh 5

您正在初始化两个副本

vector<string> DayNames = vector<string>();
Run Code Online (Sandbox Code Playgroud)

因为你包括两次标题.

你应该用它替换它

extern vector<string> DayNames;
Run Code Online (Sandbox Code Playgroud)

在h文件和

vector<string> DayNames = vector<string>();
Run Code Online (Sandbox Code Playgroud)

在cpp文件中.

你似乎也有两份副本

ostream & operator<<(ostream & out, Day cs);
Run Code Online (Sandbox Code Playgroud)

您的标题保护不帮助这种情况的原因是,当您包含标题时,您基本上复制了包含标题的所有文件中的定义.

在C中,当你声明一个变量时,你基本上实例化它/为它分配静态空间.当您将变量声明放在标题中时,您实际要做的是为两个不同对象中的变量分配静态存储空间,从而为您提供错误.