tags:

views:

1646

answers:

5

Alright, so I just finished my last compiler error (so I thought) and these errors came up:

1>GameEngine.obj : error LNK2001: unresolved external symbol "public: static double WeaponsDB::PI" (?PI@WeaponsDB@@2NA)
1>Component.obj : error LNK2001: unresolved external symbol "public: static double WeaponsDB::PI" (?PI@WeaponsDB@@2NA)
1>Coordinate.obj : error LNK2019: unresolved external symbol "public: static double WeaponsDB::PI" (?PI@WeaponsDB@@2NA) referenced in function "public: double __thiscall Coordinate::distanceFrom(class Coordinate *)" (?distanceFrom@Coordinate@@QAENPAV1@@Z)
1>Driver.obj : error LNK2001: unresolved external symbol "public: static double WeaponsDB::PI" (?PI@WeaponsDB@@2NA)
1>Environment.obj : error LNK2001: unresolved external symbol "public: static double WeaponsDB::PI" (?PI@WeaponsDB@@2NA)
1>Environment.obj : error LNK2001: unresolved external symbol "public: static bool Environment::spyFlag" (?spyFlag@Environment@@2_NA)
1>Environment.obj : error LNK2001: unresolved external symbol "private: static class Environment * Environment::instance_" (?instance_@Environment@@0PAV1@A)
1>Environment.obj : error LNK2019: unresolved external symbol "public: static void __cdecl Environment::spyAlertOver(void)" (?spyAlertOver@Environment@@SAXXZ) referenced in function "public: void __thiscall Environment::notificationOfSpySuccess(void)" (?notificationOfSpySuccess@Environment@@QAEXXZ)
1>GameDriver.obj : error LNK2019: unresolved external symbol "public: static void __cdecl MainMenu::gameOver(int)" (?gameOver@MainMenu@@SAXH@Z) referenced in function "public: static void __cdecl GameDriver::run(void)" (?run@GameDriver@@SAXXZ)
1>GameDriver.obj : error LNK2019: unresolved external symbol "public: static void __cdecl GameDriver::gatherInput(void)" (?gatherInput@GameDriver@@SAXXZ) referenced in function "public: static void __cdecl GameDriver::run(void)" (?run@GameDriver@@SAXXZ)
1>GameDriver.obj : error LNK2019: unresolved external symbol "public: static void __cdecl GameDriver::ticker(void)" (?ticker@GameDriver@@SAXXZ) referenced in function "public: static void __cdecl GameDriver::run(void)" (?run@GameDriver@@SAXXZ)
1>GameDriver.obj : error LNK2001: unresolved external symbol "public: static int GameDriver::ticks" (?ticks@GameDriver@@2HA)
1>GameDriver.obj : error LNK2001: unresolved external symbol "public: static bool GameDriver::evaluatingInputFlag" (?evaluatingInputFlag@GameDriver@@2_NA)
1>GameDriver.obj : error LNK2001: unresolved external symbol "public: static bool GameDriver::keyQuitFlag" (?keyQuitFlag@GameDriver@@2_NA)
1>GameDriver.obj : error LNK2001: unresolved external symbol "public: static bool GameDriver::keyToggleWeaponRightFlag" (?keyToggleWeaponRightFlag@GameDriver@@2_NA)
1>GameDriver.obj : error LNK2001: unresolved external symbol "public: static bool GameDriver::keyToggleWeaponLeftFlag" (?keyToggleWeaponLeftFlag@GameDriver@@2_NA)
1>GameDriver.obj : error LNK2001: unresolved external symbol "public: static bool GameDriver::keyFireFlag" (?keyFireFlag@GameDriver@@2_NA)
1>GameDriver.obj : error LNK2001: unresolved external symbol "public: static bool GameDriver::keyLeftFlag" (?keyLeftFlag@GameDriver@@2_NA)
1>GameDriver.obj : error LNK2001: unresolved external symbol "public: static bool GameDriver::keyRightFlag" (?keyRightFlag@GameDriver@@2_NA)
1>GameDriver.obj : error LNK2001: unresolved external symbol "public: static bool GameDriver::keyUpFlag" (?keyUpFlag@GameDriver@@2_NA)
1>GameDriver.obj : error LNK2001: unresolved external symbol "public: static bool GameDriver::keyDownFlag" (?keyDownFlag@GameDriver@@2_NA)
1>GUI_Env.obj : error LNK2001: unresolved external symbol "private: static struct BITMAP * GUI_Env::buffer" (?buffer@GUI_Env@@0PAUBITMAP@@A)
1>GUI_Info.obj : error LNK2001: unresolved external symbol "private: static struct BITMAP * GUI_Info::buffer" (?buffer@GUI_Info@@0PAUBITMAP@@A)
1>MenuDriver.obj : error LNK2019: unresolved external symbol "public: static void __cdecl MainMenu::displayMenu(void)" (?displayMenu@MainMenu@@SAXXZ) referenced in function "public: static void __cdecl MenuDriver::start(void)" (?start@MenuDriver@@SAXXZ)
1>SpaceObjectFactory.obj : error LNK2001: unresolved external symbol "private: static class SpaceObjectFactory * SpaceObjectFactory::_instance" (?_instance@SpaceObjectFactory@@0PAV1@A)
1>Spy.obj : error LNK2019: unresolved external symbol "public: virtual bool __thiscall UnFormationable::sameTypeOfSpaceObjectAs(class SpaceObject *)" (?sameTypeOfSpaceObjectAs@UnFormationable@@UAE_NPAVSpaceObject@@@Z) referenced in function "public: virtual bool __thiscall Spy::sameTypeOfSpaceObjectAs(class SpaceObject *)" (?sameTypeOfSpaceObjectAs@Spy@@UAE_NPAVSpaceObject@@@Z)
1>WeaponsDB.obj : error LNK2001: unresolved external symbol "private: static class WeaponsDB * WeaponsDB::_instance" (?_instance@WeaponsDB@@0PAV1@A)
1>C:\Users\Owner\Desktop\Bosconian\code\Bosconian\Debug\Bosconian.exe : fatal error LNK1120: 23 unresolved externals

Alright, here's a brief overview.

PI is a static constant in WeaponsDB and is referenced by other classes using WeaponsDB::PI and the appropriate #include (what's wrong with this?)

Most other errors stem from static variables and static methods for timers from the allegro gaming library.

What causes these errors and how might I get rid of them?

Thanks in advance

----------------Edits-------------------

As requested, where the WeaponsDB::PI is declared and defined. It is declared in WeaponsDB.h:

public:
    static double PI;

But it is defined in another class Driver.cpp:

WeaponsDB::PI = 4*atan(1.0);

If this is one of the problems with my code I would love to know why this causes an error.

+2  A: 

This

WeaponsDB::PI = 4*atan(1.0);

assigns a value to PI. It does not create space for it (does not define it).

This creates space for (defines) PI and assigns a value to (initializes) it.

double WeaponsDB::PI = 4*atan(1.0);

You should probably also mark PI as "static const" and not just "static". static makes it owned by the class instead of by the instance. const makes it immutable (and enables various optimizations).

You might also consider using M_PI from math.h instead of recreating the constant.

Edit: parenthetically added the more precise terms: defines, initializes due to WP's comment.

Mr Fooz
Hmmm...the change double WeaponsDB::PI = 4*atan(1.0);Doesn't seem to work for me (it throw errors regarding redefinition)The reason I don't make it const is I would have to define the value at compile time and I can't define floating points as const for some reason.
Chad
"it throw errors regarding redefinition" because you didn't obey what someone else commented on your question: "You need to post the part of the .h file that declares the PI and in the .cpp file that defines it." Keep the declaration in the .h file. Put one DEFINITION in one cpp file.
Windows programmer
I see this answer might not be clear enough though it's correct. "assigns a value to PI. It does not create space for it" = assigns but doesn't define. "creates space for PI and assigns a value to it" = defines and initializes.
Windows programmer
const forces you to choose the value at or before initialization time, not at compile time. Only integer member initializations can be specified in a .h file. As dribeas and WP have suggested, you need to make sure that you have a single .cpp file that defines it, creating the actual storage space
Mr Fooz
A: 

Declaring a variable in one place and assigning it a value in another place shouldn't cause any errors. Make sure you include WeaponsDB.h at the top of all files that reference objects defined there.

Ex: at the top of Driver.cpp, make sure "#include WeaponsDB.h" appears.

Hope this helps!

Pwninstein
I have the necessary #include's. I believe it would a unknown member type of error if that was the case.
Chad
+6  A: 

Most often, when the linker is failing to detect a static method it is due to forgetting to really define it somewhere, as it was pointed before:

// header
class X {
   static const int y;
};

// cpp
const int X::y = 1;

But in your case, as you are not only missing static variables but also all the rest of the members my bet is that you are not linking the implementation file(s) (.cpp) in your project. You must provide a compilation unit that defines the symbols that were declared in the header, and make the environment compile and link it together. If the symbols belong to a compilation unit in an external library (from your current project) then you must remember to link with the library.

David Rodríguez - dribeas
A: 

From reading your comments in other people's answers, it looks like you are assigning it a value inside of a function. You need to have:

double WeaponsDB::PI = 4*atan(1.0);

.. in a global scope (meaning not inside of a function) of your implementation file, presumably WeaponsDB.cpp. And in that case, "const"ing it would be appropriate. In fact, you can skip the part about putting it in your .cpp and just do it directly in WeaponsDB.h:

public:
    static const double PI = 4*atan(1.0);
Jim Buck
Depending on the compiler, only integral types can be assigned to const values in a header file.
Mr Fooz
A: 

An awful lot of static members are missing. Could it be that you concentrate your static members definitions in one file, and then you don't link that file in?

Arkadiy