Why won't my C++ program link when my class has static members?
Asked Answered
P

5

7

I have a little class called Stuff that I want to store things in. These things are a list of type int. Throughout my code in whatever classes I use I want to be able to access these things inside the Stuff class.

Main.cpp:

#include "Stuff.h"

int main()
{
    Stuff::things.push_back(123);
    return 0;
}

Stuff.h:

#include <list>

class Stuff
{
public:
    static list<int> things;
};

but I get some build errors with this code:

error LNK2001: unresolved external symbol "public: static class std::list<int,class std::allocator<int> > Stuff::things" (?things@Stuff@@2V?$list@HV?$allocator@H@std@@@std@@A) Main.obj CSandbox

fatal error LNK1120: 1 unresolved externals C:\Stuff\Projects\CSandbox\Debug\CSandbox.exe CSandbox

I am a C# guy, and I am trying to learn C++ for a side project. I think that I don't understand how C++ treats static members. So please explain what I have got wrong here.

Pattani answered 29/12, 2009 at 21:14 Comment(3)
Might I politly suggest that you try to format your code sample? :-)Eberta
I would, if I knew how, though I notice that Greg was kind enough to do it for mePattani
I was going to put my answers and...2 new answers. Just because I knew it.Minnesota
D
16

Mentioning a static member in a class declaration is a declaration only. You must include one definition of the static member for the linker to hook everything up properly. Normally you would include something like the following in a Stuff.cpp file:

#include "Stuff.h"

list<int> Stuff::things;

Be sure to include Stuff.cpp in your program along with Main.cpp.

Dyna answered 29/12, 2009 at 21:18 Comment(2)
@Greg - that should be list<int> Stuff::things;Roundish
Thanks, just noticed and fixed that :)Dyna
Y
8

Static data members have to be defined outside class declarations, much like methods.

For example:

class X {
    public:
        static int i;
};

Must also have the following:

int X::i = 0; // definition outside class declaration
Yoshi answered 29/12, 2009 at 21:18 Comment(0)
C
3

Stuff::things is only declared, but it is not defined.

please use:

// Stuff.cpp
#include "Stuff.h"

std::list<int> Stuff::things;

Added: it is also a good practice to protect your header files against multiple inclusion:

// Stuff.h
#ifndef STUFF_H_
#define STUFF_H_

#include <list>

class Stuff {
    public:
       static std::list<int> things;
};

#endif
Cenac answered 29/12, 2009 at 21:35 Comment(0)
S
2

Just For your Information, why this works is that in C++ all global variables (including static global) are created before the execution of the main function begins.

Sava answered 29/12, 2009 at 21:55 Comment(0)
A
0

Static member have to be declared in the class but defined in the unit (cpp file) where it is really located.

The only exception is in case the class is template: in this case you have to define the member outside the class, but you have to provide it too with the class declaration, in the header file.

Abbotson answered 29/12, 2009 at 21:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.