我正在为学校做一个项目。我知道我的循环依赖(并且已经在此处阅读了大部分解决方案),但它目前按照我需要的方式工作。可悲的是,我很确定这也是我困境的原因。我想包含concol.h
,以便它可以与两个文件一起使用(我想在我的输出中添加一些颜色 - 不是我的作业要求,而是我想做的事情)。我已尝试在多个不同的位置放置此标头文件,但我总是遇到相同的错误。我考虑过像我一样使用前向声明来处理循环依赖,但我认为它不适用于命名空间。
错误:
1>Flight.obj : error LNK2005: "void * eku::std_con_out" (?std_con_out@eku@@3PAXA) already defined in BoardingPass.obj
1>Flight.obj : error LNK2005: "bool eku::colorprotect" (?colorprotect@eku@@3_NA) already defined in BoardingPass.obj
1>Flight.obj : error LNK2005: "enum eku::concol eku::textcol" (?textcol@eku@@3W4concol@1@A) already defined in BoardingPass.obj
1>Flight.obj : error LNK2005: "enum eku::concol eku::backcol" (?backcol@eku@@3W4concol@1@A) already defined in BoardingPass.obj
1>Flight.obj : error LNK2005: "enum eku::concol eku::deftextcol" (?deftextcol@eku@@3W4concol@1@A) already defined in BoardingPass.obj
1>Flight.obj : error LNK2005: "enum eku::concol eku::defbackcol" (?defbackcol@eku@@3W4concol@1@A) already defined in BoardingPass.obj
1>Source.obj : error LNK2005: "void * eku::std_con_out" (?std_con_out@eku@@3PAXA) already defined in BoardingPass.obj
1>Source.obj : error LNK2005: "bool eku::colorprotect" (?colorprotect@eku@@3_NA) already defined in BoardingPass.obj
1>Source.obj : error LNK2005: "enum eku::concol eku::textcol" (?textcol@eku@@3W4concol@1@A) already defined in BoardingPass.obj
1>Source.obj : error LNK2005: "enum eku::concol eku::backcol" (?backcol@eku@@3W4concol@1@A) already defined in BoardingPass.obj
1>Source.obj : error LNK2005: "enum eku::concol eku::deftextcol" (?deftextcol@eku@@3W4concol@1@A) already defined in BoardingPass.obj
1>Source.obj : error LNK2005: "enum eku::concol eku::defbackcol" (?defbackcol@eku@@3W4concol@1@A) already defined in BoardingPass.obj
1>D:\School Stuff\Fall 2015\CIST 2362 C++ II\Final - Airline Reservation System\Debug\Final - Airline Reservation System.exe : fatal error LNK1169: one or more multiply defined symbols found
Source.cpp
#include <fstream>
#include <iostream>
#include <iomanip>
#include "FlightComparators.h" //includes Flight.h
#include "LocationComparators.h"
//prototypes
//methods
Flight.h
#ifndef FLIGHT_H
#define FLIGHT_H
#ifndef BOARDINGPASS_H
#include "BoardingPass.h"
#endif
#include <algorithm>
#include <string>
#include <vector>
#include "Location.h"
#include "Validate.h"
#include "AirlineTypeA.h"
#include "AirlineTypeB.h"
class BoardingPass;
class Flight{
private:
Location *departureLoc;
Location *destinationLoc;
char departureTime[6];
char arrivalTime[6];
int number;
int freqFlyerMiles;
int curOccupancy = 0;
Airline *plane;
vector<BoardingPass*> passengers;
public:
//constructor
Flight(Location*, Location*, string, string, int, int, char type);
//getters
Location* getDepartureLoc(){ return departureLoc; }
Location* getDestinationLoc(){ return destinationLoc; }
int getFlightNumber(){ return number; }
int getFreqFlyerMiles(){ return freqFlyerMiles; }
string getDepTime(){ return departureTime; }
string getAriTime(){ return arrivalTime; }
int getCurOccupancy(){ return curOccupancy; }
Airline* getPlane(){ return plane; }
vector<BoardingPass*> getPassengerList(){ return passengers; }
bool getIsFull(){ return this->plane->getMaxPass() > curOccupancy; }
void addPass(string, string, string);
void cancelReservation(int);
void displayPassengers();
void sortPassengers();
};
#endif
BoardingPass.h
#ifndef BOARDINGPASS_H
#define BOARDINGPASS_H
#ifndef FLIGHT_H
#include "Flight.h"
#endif
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
class Flight;
class BoardingPass{
private:
string fName;
string lName;
Flight* flight;
string seat;
public:
BoardingPass(string, string, Flight *flt, string seat);
string getFName(){ return fName; }
string getLName(){ return lName; }
string getSeat(){ return seat; }
void displayBoardingPass();
void writeBoardingPass(fstream&);
};
#endif
concol.h
#ifndef INC_EKU_IO_CONCOL
#define INC_EKU_IO_CONCOL
/*Header file to color text and background in windows console applications
Global variables - textcol,backcol,deftextcol,defbackcol,colorprotect*/
#include<windows.h>
#include<iosfwd>
namespace eku
{
#ifndef CONCOL
#define CONCOL
enum concol
{
black = 0,
dark_blue = 1,
dark_green = 2,
dark_aqua, dark_cyan = 3,
dark_red = 4,
dark_purple = 5, dark_pink = 5, dark_magenta = 5,
dark_yellow = 6,
dark_white = 7,
gray = 8,
blue = 9,
green = 10,
aqua = 11, cyan = 11,
red = 12,
purple = 13, pink = 13, magenta = 13,
yellow = 14,
white = 15
};
#endif //CONCOL
HANDLE std_con_out;
//Standard Output Handle
bool colorprotect = false;
//If colorprotect is true, background and text colors will never be the same
concol textcol, backcol, deftextcol, defbackcol;
/*textcol - current text color
backcol - current back color
deftextcol - original text color
defbackcol - original back color*/
inline void update_colors()
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(std_con_out, &csbi);
textcol = concol(csbi.wAttributes & 15);
backcol = concol((csbi.wAttributes & 0xf0) >> 4);
}
inline void setcolor(concol textcolor, concol backcolor)
{
if (colorprotect && textcolor == backcolor)return;
textcol = textcolor; backcol = backcolor;
unsigned short wAttributes = ((unsigned int)backcol << 4) | (unsigned int)textcol;
SetConsoleTextAttribute(std_con_out, wAttributes);
}
inline void settextcolor(concol textcolor)
{
if (colorprotect && textcolor == backcol)return;
textcol = textcolor;
unsigned short wAttributes = ((unsigned int)backcol << 4) | (unsigned int)textcol;
SetConsoleTextAttribute(std_con_out, wAttributes);
}
inline void setbackcolor(concol backcolor)
{
if (colorprotect && textcol == backcolor)return;
backcol = backcolor;
unsigned short wAttributes = ((unsigned int)backcol << 4) | (unsigned int)textcol;
SetConsoleTextAttribute(std_con_out, wAttributes);
}
inline void concolinit()
{
std_con_out = GetStdHandle(STD_OUTPUT_HANDLE);
update_colors();
deftextcol = textcol; defbackcol = backcol;
}
template<class elem, class traits>
inline std::basic_ostream<elem, traits>& operator<<(std::basic_ostream<elem, traits>& os, concol col)
{
os.flush(); settextcolor(col); return os;
}
template<class elem, class traits>
inline std::basic_istream<elem, traits>& operator>>(std::basic_istream<elem, traits>& is, concol col)
{
std::basic_ostream<elem, traits>* p = is.tie();
if (p != NULL)p->flush();
settextcolor(col);
return is;
}
} //end of namespace eku
#endif //INC_EKU_IO_CONCOL
答案 0 :(得分:1)
在SELECT COUNT(*)
FROM Appointment a
WHERE DATE(a.startDate) = ?1
中,您在命名空间内定义变量,而不是声明它们。变量需要concol.h
ed
extern
标题中的(定义它们),然后在.cpp文件(concol.cpp)中声明(没有extern)。
答案 1 :(得分:0)
链接器指示的符号为&#34;已定义&#34;是在头文件中声明但在任何类之外的项。 (在&#34;文件范围&#34;。)因此,包含这些头文件的每个.cpp文件都试图为它们重新定义存储。当链接器尝试将目标文件链接在一起时,它会看到这些多个定义,并且它会抱怨它们。
解决问题的最佳方法是制作所有这些项目&#34;静态数据成员&#34;一堂课。这意味着在类中声明它们,并将它们标记为static
。
如果您不想在课堂内移动它们,那么您必须确保它们将被声明为&#34; extern&#34;当包含在所有.cpp文件中但只有一个。这样,只有一个.cpp文件会尝试为它们定义存储,链接器会很高兴。
通常按如下方式进行:
a.cpp:
#define DECLARE_STORAGE
#include "myheader.h"
b.cpp,c.cpp等:
#include "myheader.h" //without defining DECLARE_STORAGE
myheader.h
#ifdef DECLARE_STORAGE
#define POSSIBLY_EXTERN
#else
#define POSSIBLY_EXTERN extern
#endif
POSSIBLY_EXTERN int my_integer;
这将导致a.cpp编译语句
int my_integer;
而b.cpp,c.cpp等将编译语句
extern int my_integer;