1

As the question states i'm trying to initalize a static class member variable using this same class's static member function but at a chosen time during runtime.

The is that the copy constructor for GameDataLocalResource is implicitly deleted because one of its fields has no copy assignement operator. So I tried to define the copy constructor but i'm still getting the same error at compilation.

How should i handle the problem. Please keep in mind i'm beginner in C++.

I looked at many thread on how to initialize a static member variable at runtime but none seems to fit my situation.

//*.h file
class GameDataResource
{

private:
    static GameDataLocalResource local_resource;

public:
    static void initializeLocalResource();
    static GameDataLocalResource  getLocalResource();
}

//*.cpp file

void GameDataResource::initializeLocalResources()
{
    GameDataResource::local_resource = GameDataLocalResource();
}

GameDataLocalResource GameDataResource::getLocalResources()
{
    return GameDataResource::local_resource;
}

//main.cpp

int main(int argc, char *argv[])
{
...
    GameDataResource::initializeLocalResources();
    qDebug() << GameDataResource::getLocalResources().getLoadingPercentage();
...
}

I expect to get the value of loading percentage but instead i get:

copy assignment operator of 'GameDataLocalResource' is implicitly deleted because field '****' has no copy assignment operator

R.J. Dunnill
  • 2,049
  • 3
  • 10
  • 21
emdou
  • 261
  • 3
  • 8
  • `getLocalResource` vs `getLocalResources`; either way, should it be returning a reference? – 1201ProgramAlarm Jun 25 '19 at 23:40
  • That's an assignment, not an initialisation. Static members need to be initialised when they're defined. I think you're looking for the Singleton. – molbdnilo Jun 25 '19 at 23:49
  • It certainly does seem like you are trying to use a singleton pattern here (i.e. only one instance of a class can be instanciated). [This question](https://stackoverflow.com/questions/1008019/c-singleton-design-pattern) and answers therof may be useful. – ChrisD Jun 25 '19 at 23:55
  • That's the thing i don't want to instanciate the Base class (GameDataResource) because a lot of other classes depend on the info it contains. Game items, characters, etc – emdou Jun 26 '19 at 00:06
  • Preferably it should return a reference yes (it would be wastful to return a copy knowing the amout of data it contains) – emdou Jun 26 '19 at 00:19
  • Sorry I misread it. If a `GameDataLocalResource` is default constructible you shouldn't need to explicitly instanciate it yourself. But yes, you should certainly be returning it by reference from `getLocalResources` – ChrisD Jun 26 '19 at 00:29

3 Answers3

1

Hello and welcome to C++ and stackoverflow. Since you are new and trying to understand the concepts of something being static there are two versions. You can read up about them from these links:

Since your question involves class members, you can focus more on the later.


How does static-members work? They do not belong to an object, they can be considered incomplete until a definition is encountered. The static keyword for class members can only be used during the declaration. The initialization of a class's static-member must be defined outside of the class.


Here is a simple example of static member initialization:

SomeClass.h

class Foo {
public:
    static int bar;
    int x;

    void someFunc();
};

Here when the class's cpp file is compiled Foo::bar has static duration and internal linkage. The static member has no association to the object of Foo but can be accessed by the class's this pointer for example:

SomeClass.cpp

int Foo::bar = 0;

void Foo::someFunc() {
    this->x = 5; // okay
    this->bar = 9; // okay as an instance of this object can access `bar` 
                   // since all instances share this static member
                   // there is only ever one instance of `Foo::bar` in memory
}

To show that it has no association to the actual instance or an object of type Foo we can see this from the example below.

SomeOtherClassOrFunction

{
    Foo f;
    f.a = 5; // okay as long as `a` is public
    f.bar = 9; // same as above `bar` is shared across all instances of Foo

    // Accessing bar we do not need an object we can do it as such:
    std::cout << Foo::bar << '\n'; // Should print 9.
}

Now that you have a general understanding of static member variables static functions follow similar rules except for the rules that govern how their address can be stored in a pointer, but that is beyond the scope of this topic. The only major difference is static member functions can be accessed by the this-pointer but have no association to that object as they are static functions.


We can take the above example and remove the non static member and change the storage class of its member function and rename it.

Foo.h

#pragma once

class Foo {
public:
    static int bar;

    static void update(int val) { bar = val; }
};

Foo.cpp

#include "Foo.h"

int Foo::bar = 0; // default initialized

main.cpp

#include <iostream>
#include "Foo.h:"

int main() {
    std::cout << "Default Foo::bar = " << Foo::bar << '\n';

    Foo::update(25);

    std::cout << "Updated Foo::bar = " << Foo::bar << '\n';

    return 0;
}

I'm not sure if this is the exact behavior you are looking for, but this is the basic or general concepts and usages of static class members. Hopefully this will give you some insight.

Francis Cugler
  • 7,788
  • 2
  • 28
  • 59
  • 1
    Thank you for the refresher ! It's always welcome. I understand the concept of static-members the problem was that 'the copy constructor for GameDataLocalResource is implicitly deleted because one of its fields has no copy assignement operator' so i couldn't assign a value to the static member instance unless it was in the *.cpp file : GameDataResource::local_resource = GameDataLocalResource(); Which causes it be initialize before the main function is executed. Thank you for your truly instructive answer +1. – emdou Jun 26 '19 at 21:46
0

GameDataLocalResource is a type and not a function which can initialize the static variable.May be this solves your problem.

  • The thing is creating a GameDataLocalResource instance initializes its members by loading a bunch of files (as QJsonObjects) into memory. I would like to be able to do that manually. – emdou Jun 26 '19 at 00:04
0

So the solution I found was hinted in an answer that was deleted. Mainly I added a new member function to GameDataLOCALResource that initializes its "heavy" members.

By doing so I able to make an instance of it without loading the files.

Then a call to a static member function of GameDataResource triggers the GameDataLOCALResource instance to load the files into its member variables.

Thanks everyone !

emdou
  • 261
  • 3
  • 8