0

I have some simple hypothetical static class in C++:

#ifndef __STAT_H_
#define __STAT_H_

class Stat {

 private:
  static vector<int> v;

 public:

  static void add_num(int num);
  static void clear_nums();
  static void get_count();
};

#endif

And the ccp file is so:

#include "Stat.h"

vector<int> v;


void Stat::add_num(int num) {
  v.push_back(num);
}

void Stat::clear_nums() {
  v.clear();
}

int Stat::get_num_count() {
  return v.size();
}

Now when I include in main.cpp file "Stat.h" and try to use some static method:

Stat::add_num(8);

the error during compilation is

undefined reference to 'Stat::add_num(int)'

What can be the problem in this case? Thank you.

EDIT: sorry about addresses vector, it should be v there

Sergey
  • 11,548
  • 24
  • 76
  • 113
  • 1
    Most likely one of these (I'm looking at you, didn't link implementation): http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix. You also might find this interesting: http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier – chris Dec 09 '12 at 08:04
  • You should explain what compilation command you are using, and what compiler you have. – Basile Starynkevitch Dec 09 '12 at 08:05
  • command is: g++ main.cpp – Sergey Dec 09 '12 at 08:09
  • Note: Your include guard is not valid according to the standard. All names beginning with a leading underscore followed by a capital letter are reserved by the implementation in the global namespace. (And as it is a macro, that is included) Names with double underscores are disallowed in all contexts. But that is unrelated to your question. – Billy ONeal Dec 09 '12 at 08:12
  • This is unrelated to the error, but there is no concept of static classes in C++. – juanchopanza Dec 09 '12 at 08:25
  • `static void get_count();` in your header is inconsistent with the declaration in your `.cpp` file. – Dennis Dec 09 '12 at 08:31

3 Answers3

3

It sounds like you have not included stat.cpp in compilation. So your linker cannot find an implementation for the static methods.

unknownuser
  • 790
  • 9
  • 16
  • 2
    +1. I would additionally note that the declaration of `v` is wrong. It declares a vector `v`, not `Stat::v`. – Billy ONeal Dec 09 '12 at 08:11
  • I included stat.h into main.cpp – Sergey Dec 09 '12 at 08:14
  • 1
    @Sergey: But you didn't tell the compiler about `stat.cpp` -- which is where `Stat::add_num` is defined. So the compiler (or rather, in this case the linker) is perfectly okay in saying "I don't know where to find this definition". – Billy ONeal Dec 09 '12 at 08:15
  • See http://stackoverflow.com/questions/3202136/using-g-to-compile-multiple-cpp-and-h-files – unknownuser Dec 09 '12 at 08:16
  • if I change stat.h to stat.cpp in include directive, it's the same error – Sergey Dec 09 '12 at 08:18
  • You wouldn't change the include, you need to pass the cpp to the compiler itself. See the link I posted above. – unknownuser Dec 09 '12 at 08:20
1

You need to link Stat.o in g++ command, say:

g++ -c -o Stat.o Stat.cpp
g++ -o Stat main.cpp Stat.o

I guess in your Stat.cpp:

vector<int> v;

should be:

vector<int> Stat::v;

There is no compile error if you define local v in Stat.cpp but I guess you intent to use Stat::v

billz
  • 44,644
  • 9
  • 83
  • 100
1

Here's my take on your program, just for reference sake.

Stat.h

#ifndef STAT_H
#define STAT_H

#include <vector>
using std::vector;

class Stat
{
 public:
  static void add_num(int num);
  static void clear_nums();
  static int get_count();

 private:
  static vector<int> v;
};

#endif

Stat.cpp

#include "Stat.h"

vector<int> Stat::v;

void Stat::add_num(int num) { v.push_back(num); }

void Stat::clear_nums() { v.clear(); }

int Stat::get_count() { return v.size(); }

main.cpp

#include "Stat.h"

int main()
{
  Stat s;
  s.add_num(8);
}

Makefile

CC = g++
OBJS = Stat.o
DEBUG = -g
CFLAGS = -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)

all: build clean

build: $(OBJS)
        $(CC) main.cpp $(LFLAGS) $(OBJS) -o stat

Stat.o: Stat.h
        $(CC) $(CFLAGS) Stat.cpp

clean:
        -rm -f *.o
Dennis
  • 56,821
  • 26
  • 143
  • 139