0

Я работаю над проектом для школы. Я знаю свою круговую зависимость (и прочитал большинство резолюций здесь для этого ранее), но он работает в настоящее время так, как мне это нужно. К сожалению, я уверен, что это также причина моих беды. Я хотел бы включить concol.h, чтобы он мог использоваться с обоими файлами (я хотел бы добавить некоторый цвет к моему выводу - не требование для моего задания, а то, что я хотел бы сделать). Я попытался разместить этот файл заголовка в нескольких разных местах, и я всегда получаю те же ошибки. Я рассматривал использование форвардного объявления, как я сделал для работы с круговой зависимостью, но я не думаю, что это будет работать с пространством имен.Ошибка C++ LNK2005 При добавлении нового заголовка

Ошибки:

1>Flight.obj : error LNK2005: "void * eku::std_con_out" ([email protected]@@3PAXA) already defined in BoardingPass.obj 1>Flight.obj : error LNK2005: "bool eku::colorprotect" ([email protected]@@3_NA) already defined in BoardingPass.obj 1>Flight.obj : error LNK2005: "enum eku::concol eku::textcol" ([email protected]@@[email protected]@A) already defined in BoardingPass.obj 1>Flight.obj : error LNK2005: "enum eku::concol eku::backcol" ([email protected]@@[email protected]@A) already defined in BoardingPass.obj 1>Flight.obj : error LNK2005: "enum eku::concol eku::deftextcol" ([email protected]@@[email protected]@A) already defined in BoardingPass.obj 1>Flight.obj : error LNK2005: "enum eku::concol eku::defbackcol" ([email protected]@@[email protected]@A) already defined in BoardingPass.obj 1>Source.obj : error LNK2005: "void * eku::std_con_out" ([email protected]@@3PAXA) already defined in BoardingPass.obj 1>Source.obj : error LNK2005: "bool eku::colorprotect" ([email protected]@@3_NA) already defined in BoardingPass.obj 1>Source.obj : error LNK2005: "enum eku::concol eku::textcol" ([email protected]@@[email protected]@A) already defined in BoardingPass.obj 1>Source.obj : error LNK2005: "enum eku::concol eku::backcol" ([email protected]@@[email protected]@A) already defined in BoardingPass.obj 1>Source.obj : error LNK2005: "enum eku::concol eku::deftextcol" ([email protected]@@[email protected]@A) already defined in BoardingPass.obj 1>Source.obj : error LNK2005: "enum eku::concol eku::defbackcol" ([email protected]@@[email protected]@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

Возможный дубликат [LNK2005 ошибки: новые и удалять уже определены в LIBCMTD.lib (новый .obj)] (http://stackoverflow.com/questions/1146338/error-lnk2005-new-and-delete-already-defined-in-libcmtd-libnew-obj) –

+0

@KenWhite, возможно, для вас это дубликат, но Я лично недостаточно далеко, чтобы даже понять, что там происходит с dll и статическими библиотеками. – Alyssa

ответ

1

В concol.h вы определяете переменные внутри пространства имен, не объявляя их. Переменные должны быть extern Эду

extern HANDLE std_con_out; 

в заголовке (для их определения), затем декларированная (без экстерном) в .cpp файле (concol.cpp).

+0

ах это имеет смысл. Я попробую это. файл concol.h не был написан мной, но был получен с http://www.cplusplus.com/articles/Eyhv0pDG/ - к сожалению ... нет возможности оставлять вопросы или комментарии к этой статье. – Alyssa

0

Символы, обозначенные компоновщиком как «уже определенные», являются элементами, объявленными в заголовочных файлах, но вне любого класса. (В «области файла».) В результате каждый .cpp-файл, который включает эти файлы заголовков, пытается переопределить хранилище для них. Когда компоновщик пытается связать объектные файлы вместе, он видит эти множественные определения и жалуется на них.

Лучшее, что нужно сделать для решения вашей проблемы, состоит в том, чтобы сделать все эти элементы «статическими элементами данных» класса. Это означает объявление их в классе и обозначение их как static.

Если вы не хотите перемещать их внутри класса, вы должны убедиться в том, что они будут объявлены как «внешние», если они включены во все файлы .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.каст составить заявление

int my_integer; 

в то время как b.cpp, c.cpp и т.д. компилирует заявление

extern int my_integer; 
+0

Я попытался использовать этот метод. Bu VS продолжает отмечать '#define POSSIBLY_EXTERN extern' как« блок неактивного препроцессора ». – Alyssa

+0

. Вы устранили ошибки? Как? В чем была проблема? –

+0

Мне не удалось устранить эту ошибку, поэтому в настоящее время я отказался от использования цвета в этом проекте. Я не мог определить причину или исправить блоки запрещенных препроцессоров. Из того, что я прочитал, это происходит, когда определено, что блок никогда не будет использоваться, но для этого не было причин. – Alyssa