0

So here are my classes:

class A 
{
   public:

   static MyObject *getObject(std::string string)
   {  
       if(string == "string1")
           return object1; 
       else if(string == "string2");
           return object2;
       else 
           return object3;
   }


   static MyObject *object1;
   static MyObject *object2;
   static MyObject *object3;
}

#include "A.h"

class B
{

    public:

    void initMethod();

    void myMethod();

}

 //B.cpp file
 #include "B.h"

 void B::init()
 {
     A::object1 = new MyObject();
     A::object2 = new MyObject();
     A::object3 = new MyObject();
  }

  void B::myMethod
  {
    MyObject *currentObject = A::getObject("string1");

     //Do stuff with MyObject
  }

As you can see, I am first trying to initialize the members of A inside of B and then access those members later on in a different function. However, any time I try to access the A class data inside B, I get an "undefined symbol for architecture x86_64" compiler error and I can't seem to figure out why. What am I doing wrong?

user1855952
  • 1,515
  • 5
  • 26
  • 55
  • http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix – chris May 24 '14 at 03:59
  • what' s the actual error message? Is it tirggered by some line? – feverzsj May 24 '14 at 14:13

2 Answers2

0

Several errors with your code:

  1. You are using Class B, should be class B
  2. initMethod and myMethod lacks () after them
  3. The static members in A must be defined in a source(.cpp) file, otherwise you will get linker error.

So for ex. in your main.cpp file you have to define them

MyObject* A::object1 = new MyObject(/*param*/);
//others

Edit According to OP's comment, I think you should learn about object lifetime and variable scope. You can check these links 1, 2,3. You can also search for more. In particular, static variables have the lifetime of whole program lifetime once they are created. So static variables declared in a method has lifetime once the method is entered, the variable created and then until program terminates. Class level, global static variables have lifetime which starts before main (or before program execution starts), and remains alive until program terminates. In your case, since you are creating static variable at class level, compiler will try to keep them in memory before program starts, and for this, they have to be visible/defined in an accessible region. That's why you have to define them outside your member method.

Once I do that I can then initialize them in my init()? What if I then want to use the same objects in another class, say class C? Would I have to redefine them in C.cpp all over again?

  1. yes, you can just define them without initializing (they will be created with default values), then you can use init() method to assign correct value.

    MyObject *currentObject; //in global scope //then assign in init

    A::object1 = new MyObject();

  2. no, you have to define only once. In any other class/method you will be able to refer the same variable using A::object1 .. etc.

Community
  • 1
  • 1
Rakib
  • 7,435
  • 7
  • 29
  • 45
  • As per 1 and 2 - those are not errors within my actual code...just typos when typing it here on StackOverflow. As for 3: In my actual code, I am actually initializing them in a .cpp file. The implemenation for class B init() is done in my B.cpp – user1855952 May 24 '14 at 04:09
  • have u tried initializing in global scope other than in `initMethod`? – Rakib May 24 '14 at 04:13
  • I cannot do that because MyObject takes in a parameter passed in from class B – user1855952 May 24 '14 at 04:13
  • 1
    they must be defined outside a method. can just write like `MyObject* A::object1;`. don't have to allocate them, just define. – Rakib May 24 '14 at 04:15
  • Once I do that I can then initialize them in my init()? What if I then want to use the same objects in another class, say class C? Would I have to redefine them in C.cpp all over again? – user1855952 May 24 '14 at 04:17
-1

Static members need to be defined at global scope (they are static global variables), like this :

class A {
public:
  static int i; // declaration, not definition.
};

int A::i; // definition (initialization here is not mandatory, but be careful...)

int main(...) {
  A::i = 0; // complex initialization can be performed here...
  ...
}

Initialization of static members can be sometimes very tricky, especially when there is dependencies in between.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
  • "they are static global variables" is very misleading. Static global variables have static linkage, but class members do not. And the definition should be in the namespace containing the class, not always the global namespace. – Ben Voigt May 24 '14 at 15:41