0

When I try to compile this code, why does g++ report an error?

class A {
  private:
    static A* Aptr[5];
  public:
    static int A_count;
    A() {
        Aptr[A_count] = this;
    }
};

int A::A_count = 0;

int main() {
    A a_;
    A b_;
    return 0;
}

/tmp/ccrp4BGg.o: In function `A::A()':
try.cpp:(.text._ZN1AC2Ev[_ZN1AC5Ev]+0x18): undefined reference to `A::Aptr'
collect2: error: ld returned 1 exit status
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
user1135541
  • 1,781
  • 3
  • 19
  • 41

4 Answers4

5

Explanation

You have only declared your static data-member named A::Aptr, but in order to use it, as you are inside the constructor of A, you must provide a definition.

The linker diagnostic might say undefined reference, which might be hard to relate to a missing definition, but it's talking about its internal mapping of names and storage location.

In other words; the linker is unable to find a a reference (ie. entry) for the location where A::Aptr is stored, which makes sense: Without a definition you haven't given A::APtr any storage to use.


Solution

You've already provided both a declaration (2), and a definition (4) for A::A_count, if you do the same for A::APtr you will be all set.

class A {
 private:
    static A* Aptr[5];   // (1), declaration
 public:
    static int A_count;  // (2), declaration
    A() {
        Aptr[A_count] = this;
    }
};

A*  A::APtr[5];     // (3), definition  <-- previously missing! 
int A::A_count = 0; // (4), definition

Note: You are only asking about the linker error, but I'm guessing you mean to increment A_count upon constructing an object of type A, something which you are currently not doing.

Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
1

You need to define it outside the class, just like any other static variable:

kirbyfan64sos
  • 10,377
  • 6
  • 54
  • 75
0

Because it is static you need to define Aptr outside of the class, right now you have only declared it but not defined and initialized it. This means that the linker can't find it. Also do you want to increment A_count?:

class A {
 private:
    static A* Aptr[5];
 public:
    static int A_count;
    A() {
        Aptr[A_count] = this;
        A_count++; //I presume you want to do something like this too
    }
};

int A::A_count = 0;
A* A::Aptr[5] = { nullptr }

int main() {
    A a_;
    A b_;
    return 0;
}
shuttle87
  • 15,466
  • 11
  • 77
  • 106
  • Note: The initializers are redundant, as static data is always value-initialized. – M.M Jun 05 '14 at 01:48
0
class A {
  private:
    static A* Aptr[5];
  public:
    static int A_count;
    A() {
        Aptr[A_count] = this;
    }
    //static ctor
    static A(){
         Aptr=new A[5];
         A_count=0;
    }
};


int main() {
    A a_;
    A b_;
    return 0;
}
neutrino
  • 169
  • 1
  • 3
  • Good point, this time I am working on embedded system with no heap, but this looks like a cleaner solution if there is not already a source file. Hate create source files for just one line. – user1135541 Jun 05 '14 at 11:48