1

We have classes A, B and C, all of which need access to a static variable staticVariable in class D.

Moreover, class A needs to have an instance of classes B and C like this:

    class A{
    public:
    B instanceB;
    C instanceC;
    };

Class D hold the static variable of object type T:

    class D{
    public:
    D() {
    staticVariable.init();
    };
    static T staticVariable;
    };

In the example classes B and C can be empty placeholder classes:

    class B{
    };

    class C{
    };

The main function creates an instance of A:

    int main(){
    A a;
    /*...*/
    }

Again, classes A, B and C need access to staticVariable. I've tried multiple approaches including inheritance and friend functions, however I always get dependency issues or linker errors I don't quite understand:

    Error   LNK2001 unresolved external symbol "public: static class T 
    D::staticVariable" (?window@D@@2VT@sf@@A)   SortingAlgorithms    
    C:\Users\Dusan\source\repos\SortingAlgorithms\SortingAlgorithms\B.obj       

is being reported in .obj files of classes A, B and C.

I'm not sure if I need an instance of D in main.
How do I implement this error-free?
And how do you do it for static objects that call a function for initialization?
I meant if the function is of the same class as the object you're trying to initialize, and is non-static, I can't seem to be able to call staticVariable.init();

anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • 1
    Linker errors? Like these? https://stackoverflow.com/questions/5019856/initialize-static-variables-in-c-class – IWonderWhatThisAPIDoes Feb 16 '21 at 13:12
  • 3
    Please show one of your failed attempts. It is not clear what problems you are struggling with. You can acces it via `D::staticVariable`. However, note that in the code you posted the static member is not defined. Whether this is also the issue in your real code we can only know when you post a [mcve] – 463035818_is_not_an_ai Feb 16 '21 at 13:12
  • @IWonderWhatThisAPIDoes I clarified the code, 'staticVariable' is initialized in constructor of D. –  Feb 16 '21 at 13:15
  • the line you added changes nothing about my comment. You need a definition of the static variable. Static variables are not initialized in the constructor. Please post a [mcve] and the resulting error message – 463035818_is_not_an_ai Feb 16 '21 at 13:16
  • 2
    @yomag1234 You don't initialize in a constructor (static things are like global, they are not bound to an object). You have to initialize them just outside the class (in your implementation file, like `Type Class::Variable = Value;` – IWonderWhatThisAPIDoes Feb 16 '21 at 13:19
  • @largest_prime_is_463035818 I added the linker error now if that helps. –  Feb 16 '21 at 13:21
  • sorry, but thats just a fragment of the full message. The full message contains detailed information on what is wrong in your code. – 463035818_is_not_an_ai Feb 16 '21 at 13:22
  • @IWonderWhatThisAPIDoes so if static variables are more objects that call functions for initialization, I can do it anywhere? –  Feb 16 '21 at 13:23
  • You should indent your code properly. – Jabberwocky Feb 16 '21 at 13:24
  • @yomag1234 also non-static members are not initialized in the body of the constructor (though thats a different issue, only semi related). See eg here for definition of static members: https://stackoverflow.com/questions/3536372/defining-static-members-in-c – 463035818_is_not_an_ai Feb 16 '21 at 13:24
  • @yomag1234 You mean if the static member is a class-type object itself? It is similar, initialize it the same way by calling a constructor. Just don't "do it anywhere," do it in the implementation (.cpp) file that also implements member functions of class D (that goes also when the static member is not a class object) – IWonderWhatThisAPIDoes Feb 16 '21 at 13:26
  • @largest_prime_is_463035818 I clarified that staticVariable is an object type and included the whole error code, hope this helps. –  Feb 16 '21 at 13:29
  • @IWonderWhatThisAPIDoes Thank you that's what I meant. –  Feb 16 '21 at 13:29
  • yes I saw that. Your question can be considered as duplicate of this one: https://stackoverflow.com/questions/3536372/defining-static-members-in-c. I just can't flag it anymore – 463035818_is_not_an_ai Feb 16 '21 at 13:30

2 Answers2

3

I'm not sure if I need an instance of D in main.

You don't. static variables are global, they are shared by all the instances of the same class and you don't need to instantiate a class to be able to use such variables so they must be initialized regardless of class instantiation. That being the case they need to be initialized outside the class.

How do I implement this error-free?

Something like:

class B{};

class C{};

class A{
public:
    B instanceB;
    C instanceC;
};

class D{
public:
    D(){};
    static int staticVariable;
};

int D::staticVariable = 10; //<-- here, outside the class

int main()
{
    //no instance of D needed
    std::cout << D::staticVariable; // prints 10
    D::staticVariable++;
    std::cout << D::staticVariable; // prints 11 
}

And how do you do it for static objects that call a function for initialization?
I meant if the function is of the same class as the object you're trying to initialize, and is non-static, I can't seem to be able to call staticVariable.init();

It's the same principle, you declare the object static within the class and initialize it outside:

class A{
public:
    void init(){std::cout << "Do Something";} //non-static method
};

class D{
public:
    static A obj; //declare
};

A D::obj{};  //<-- initialize outside the class

int main()
{
    D::obj.init();  // prints 'Do Something'
}
anastaciu
  • 23,467
  • 7
  • 28
  • 53
1
// in D.hpp
class D {
public:
  D() { ... }; // staticVariable is static, so the ctor has no business initializing it
  void init();  

  static int staticVariable;
  static D staticD;
};

// in D.cpp
#include "D.hpp"

int D::staticVariable = 10;
// Immediatly invoked initializing lambda expression
D D::staticD = []{ D tmp; tmp.init(); return tmp; }();
m88
  • 1,968
  • 6
  • 14