2

I'm not sure what I'm doing wrong, I thought everything is defined exactly once and everything is linked correctly, but I guess that won't be the case...

Here's the errors my compiler gives me:

1>StaticElements.obj : error LNK2001: unresolved external symbol "private: static int Powerup_Health::g_refCount" (?g_refCount@Powerup_Health@@0HA)
1>StaticElements.obj : error LNK2001: unresolved external symbol "private: static class DBModel * Powerup_Health::g_pModel" (?g_pModel@Powerup_Health@@0PAVDBModel@@A)
1>StaticElements.obj : error LNK2001: unresolved external symbol "private: static int Powerup_QuadDamage::g_refCount" (?g_refCount@Powerup_QuadDamage@@0HA)
1>StaticElements.obj : error LNK2001: unresolved external symbol "private: static class DBModel * Powerup_QuadDamage::g_pModel" (?g_pModel@Powerup_QuadDamage@@0PAVDBModel@@A)

Code:

StaticElements.h

#pragma once

#include "D3DUtil.h"

class ContentManager;
class Level;
class GraphCamera;
class Powerup_Health;
class Powerup_QuadDamage;

class StaticElements
{
public:
    StaticElements(){};
    ~StaticElements(){};

    void PreLevelInitialisation(Level* pLevel);
    void PostLevelInitialisation();

private:
    Powerup_Health* m_pPwrHealth;
    Powerup_QuadDamage* m_pPwrQuadDamage;
};

StaticElements.cpp

#include "StdAfx.h"

#include "StaticElements.h"

#include "Level.h"

#include "DBModel.h"

#include "Powerup_Health.h"
#include "Powerup_QuadDamage.h"


void StaticElements::PreLevelInitialisation(Level* pLevel)
{
//////POWERUPS
    Powerup_Health::InitModel();
    m_pPwrHealth = new Powerup_Health();
    pLevel->AddChild(m_pPwrHealth);

    Powerup_QuadDamage::InitModel();
    m_pPwrQuadDamage = new Powerup_QuadDamage();
    pLevel->AddChild(m_pPwrQuadDamage);
}

Powerup_QuadDamage.h

#pragma once

#include "Powerup.h"

class Powerup_QuadDamage : public Powerup
{
private:
    //static
    static DBModel* g_pModel;
    static int g_refCount;

public:
    virtual ~Powerup_QuadDamage() {
        --g_refCount;
        if (g_refCount == 0) delete g_pModel;
    }

    Powerup_QuadDamage()
        :Powerup(g_pModel, 90.0f)
    {
        ++g_refCount;
    }

    static void InitModel() {
        g_refCount = 0;

        DBModelDesc desc;
        g_pModel = new DBModel(desc, nullptr);
    }

private:
    //disabled
    Powerup_QuadDamage(const Powerup_QuadDamage& b);
    Powerup_QuadDamage& operator= (const Powerup_QuadDamage& b);
};

Powerup_Health.h

#pragma once

#include "Powerup.h"

class Powerup_Health : public Powerup
{
private:
    //static
    static DBModel* g_pModel;
    static int g_refCount;

public:
    virtual ~Powerup_Health() {
        --g_refCount;
        if (g_refCount == 0) delete g_pModel;
    }

    Powerup_Health()
        :Powerup(g_pModel, 20.0f)
    {
        ++g_refCount;
    }

    static void InitModel() {
        g_refCount = 0;

        DBModelDesc desc;
        g_pModel = new DBModel(desc, nullptr);
    }

private:
    //disabled
    Powerup_Health(const Powerup_Health& b);
    Powerup_Health& operator= (const Powerup_Health& b);
};

Can anyone tell me what is causing the error and how to fix it please? Thanks a bunch.

xcrypt
  • 3,276
  • 5
  • 39
  • 63

1 Answers1

7

static member variables have to be initialized explicitly at the module level. Add something like the following in your cpp file:

int Powerup_Health::g_refCount = 0;
thesamet
  • 6,382
  • 2
  • 31
  • 42
  • can it also be defined in the header? – xcrypt Dec 31 '11 at 03:12
  • Generally not, you want it to appear in only one compilation unit. – Basile Starynkevitch Dec 31 '11 at 03:39
  • What if you include the Powerup_Health in many other classes, do all those cpp files need the static initialization? Seems painful if true... – Nigel Apr 29 '13 at 15:08
  • 1
    @Nigel, you only need to initialize Powerup_Health::g_refCount in one place (usually at the corresponding cpp file). Any cpp objects that depend on Powerup_Health will need to be linked with Powerup_health. – thesamet Apr 29 '13 at 19:26