problem with 'static' in class

Started by
22 comments, last by XTAL256 16 years ago
Ok, well i omitted some stuff to avoid explaining the entire structure of all my classes and stuff. My graphics stuff is in namespace 'allegx' (my wrapper around Alegro) and my GUI stuff is in namespace 'gui'. I don't think i have made any errors using the namespaces and unless a namespace error can cause a link error then i don't think that's the problem.
If i have some functions in a cpp file and not in a class (i.e. my graphics functions) do i have to make them static. I noticed that i had to make other functions static so i didn't get multiple symbols during linking but that didn't happen in this case.
[Window Detective] - Windows UI spy utility for programmers
Advertisement
Quote:Original post by XTAL256
like i said above, see my previous post. The error was:


Let's see here. You say that there was a linker error when you didn't have the static keyword, but only mention the compiler error that occurs when you add the static keyword. MSVC error codes starting with a C are compiler errors, not linker errors. Therefore you hadn't actually posted the original linker error.

In any case, are you sure that you defined the original function in the same namespace that you declared it in?
Quote:Original post by XTAL256
don't think i have made any errors using the namespaces and unless a namespace error can cause a link error then i don't think that's the problem.


I don't know what you mean by a "namespace error", but if you declare a function allegx::drawImage and then only implement a function called drawImage, the linker will correctly complain that allegx::drawImage isn't defined. It's called a namespace because it becomes part of the typename... it absolutely can cause linker programs.

No offense, but you might want to be a bit less dismissive of or impatient with our questions and advice. We're trying to help you here with basically zero information to work from.

Also, your error message is referring to a function 'void allegx::drawImage(allegx::Image *,int,int,int,int,int,int,int,int)', but your code snippets only show 'void drawImage(Image*, int, int)', so the dclaration and definition snippet you posted is completely unrelated to the problem.

Quote:If i have some functions in a cpp file and not in a class (i.e. my graphics functions) do i have to make them static. I noticed that i had to make other functions static so i didn't get multiple symbols during linking but that didn't happen in this case.

'static' makes no sense in reference to a function that isn't a class method, so no. You should just have to have a declaration that is visible to your source code, and an implementation that is linked.
@SiCrane: sorry, you're right. I posted the same error twice! I'm getting a bit confused here.
I try to omit irrelevant details like the number of function arguments (because i know i got that right) by saying something like allegx::drawImage(allegx::Image *,...) where ... is the rest of the arguments. But, yes, i did forget to do that once smitty.
I think i have probably done something wrong somewhere, i always manage to do something wrong. It's not that i'm a n00b, i'm just used to programming in Java where you don't have to worry about header files. I guess i'll figure it out eventually.
[Window Detective] - Windows UI spy utility for programmers
Quote:Original post by SiCrane
In any case, are you sure that you defined the original function in the same namespace that you declared it in?


Quote:Original post by XTAL256
I try to omit irrelevant details like the number of function arguments (because i know i got that right) by saying something like allegx::drawImage(allegx::Image *,...) where ... is the rest of the arguments.


But those aren't irrelevant details. Those are exactly the sort of details that are probably causing your problem.

As I said before--as as SiCrane seems to be hinting rather conspicuously [grin]--your problem is most likely that you declared the function inside of the namespace, but defined it without the namespace.

Why don't you just post your code?
Quote:Original post by XTAL256
like i said above, see my previous post. The error was:
C:\...\VC\include\xlocnum(235) : error C2129: static function 'void allegx::drawImage(allegx::Image *,...)' declared but not defined

Ok, well that's what i got when i made 'drawImage' static. If i don't have it static i get unresolved symbol error.


Well according to this error drawImage has definately been declared in the allegx namespace, but have you made sure that its definition counterpart is also in the allegx namespace?
Quote:Original post by smitty1276
Why don't you just post your code?

Alright, if you are willing to look through it all. I will, however, only include the code for which i get the errors. i.e. there is no need for me to include all the graphics initialisation code that is in the function. :)
// ballistic/Ballistic.h#ifndef _BALLISTIC_H_#define _BALLISTIC_H_#include <windows.h>    // Use <winalleg.h> if <allegro.h> is included#include <sstream>#include "utils/utils.h"#include "resource.h"#define ALLEGRO_STATICLINK#include "allegro/timer.h"#include "allegro/sound.h"//#include <allegro.h>    // This is how it's done for Windows but i//#include <winalleg.h>   // only need timer and sound#include "graphics/graphics.h"#include "sound/sound.h"#include "thread/Thread.h"#include "thread/Timer.h"#include "gui/gui.h"static bool fullscreen;void initWindow(bool fullscreen=true, int width=800, int height=600);void destroyWindow();int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdLine, int wndState);#endif  // _BALLISTIC_H_// graphics/graphics.h#ifndef _GRAPHICS_H_#define _GRAPHICS_H_#include <gl/gl.h>#include "Image.h"#include "Animation.h"#include "Colour.h"#include "Font.h"namespace allegx {void initGraphics();void shutdownGraphics();// Wrapper functions around OpenGL's display list functionsinline void beginList(GLuint &id) { id = glGenLists(1); glNewList(id, GL_COMPILE); }inline void endList() { glEndList(); }inline void callList(GLuint id) { glCallList(id); }// Drawing functionsvoid drawLine(int x1, int y1, int x2, int y2);void drawRect(int x, int y, int w, int h);void drawImage(Image* img, int x, int y);void drawImage(Image* img, int x, int y, int w, int h,         int wrapX = IMG_STRETCH, int wrapY = IMG_STRETCH, float angle = 0.0f);void drawImage(Image* img, int x, int y, int w, int h,         int imgX, int imgY, int imgW, int imgH);} // namespace allegx #endif  // _GRAPHICS_H_// graphics/Graphics.cpp#include "ballistic/Ballistic.h"using namespace allegx ;/* Intialise the graphics routines internally */void initGraphics() {}/* Shutdown the graphics routines internally */void shutdownGraphics() {}void drawImage(Image* img, int x, int y) {}void drawImage(Image* img, int x, int y, int w, int h,                int wrapX, int wrapY, float angle) {}void drawImage(Image* img, int x, int y, int w, int h,                int imgX, int imgY, int imgW, int imgH) {}// drawAnim, etc// gui/Button.hnamespace gui {class Button : public Component {public:    // Images used for all objects of this component.    static Image *upImg, *downImg, *hoverImg;    static int divLeft, divRight;    static void loadImages();    GLuint dlUp, dlHover, dlDown;    Button() {}    Button(String text, int x, int y, int w = 150, int h = 50);    void draw();    void update();};} // namespace gui#endif  // _GUI_BUTTON_H_// gui/Button.cpp#include "ballistic/Ballistic.h"using namespace gui;Image* Button::upImg = NULL;Image* Button::downImg = NULL;Image* Button::hoverImg = NULL;int Button::divLeft = 0;int Button::divRight = 0;Button::Button(String text, int x, int y, int w, int h) {    this->text = text;    this->x = x;      this->y = y;    this->width = w;  this->height = h;    this->state = BUTTON_UP;    update();}/* Updates the component's image when one of it's properties changes */void Button::update() {    drawImage(upImg, x, y);}void Button::draw() {    // Not done yet}void Button::loadImages() {    // Not done yet}

I think that's all. I haven't implemented anything else (except WinMain) so the functions have nothing in them
[Window Detective] - Windows UI spy utility for programmers
Yeah, it's exactly what we've been telling you... you are declaring it inside of the namespace, but defining it without the namespace. You can't simply put a "using namespace blah" statement in front of it like you are doing. If that were possible, your Button.cpp file would just have a "using namespace Button;" at the top and would omit the "Button::" in front of method names. The problem with that, of course, is that you would then be unable to define those function names in the global namespace... you would be implicitly tainting a different namespace (which defeats the purpose of namespaces) so that is why its illegal.

Examples...

namespace allegx{  void initGraphics();}using namespace allegx;// **** This defines ::initGraphics, not allegx::initGraphics ***void initGraphics() {}


Fix it by including the namespace, just like you do in the class definitions..
namespace allegx{  void initGraphics();}// **** This defines allegx::initGraphics ***void allegx::initGraphics() {}


EDIT: Here is some info from the MSDN page for the using declaration:
Quote:When a using declaration is made, the synonym created by the declaration refers only to definitions that are valid at the point of the using declaration. Definitions added to a namespace after the using declaration are not valid synonyms.
You are employing the using directive, but the rules and the logic behind them still hold.

[Edited by - smitty1276 on April 2, 2008 3:47:03 AM]
Oh ok, well like i said, i'm used to Java. I didn't know there was a problem with namespaces. I say "using namespace gui" at the top of Button.cpp but i thought that "Button::" was refering to the class Button. See that's what i'm confused about, you use "blah::blah" to resolve namespaces as well as classes. So since i don't do "gui::Button::draw()" (and i don't have to do i?) so since my graphics functions aren't in a class called Graphics then i assumed that i didn't have to put "graphics::" before it.
I have read the info on MSDN before but i still don't really understand. I will read up more on namespaces.
yay, it compiles! thanks
[Window Detective] - Windows UI spy utility for programmers

This topic is closed to new replies.

Advertisement