0

I have this struct:

struct Parameters {
    int x;
    double y;
    .
    .
    .
    float z;
}

and a Matrix class.

this struct should be initialized by reading it from a file and remains const till the end.

how can I access those from all classes in program? I managed to do it with a singleton but it did not feel right.

I also tried with static but I failed because i have to initialized the fields somehow

i want something like:

class Consts {
    Parameters _params;
    Matrix _k;
} 

and be able to access it like:

class OtherClass {
public:
    void foo() {
        Matrix a = Consts::_k;
        int b = Consts::_params.x;
    }
}
eneski
  • 1,044
  • 10
  • 30
asaf anter
  • 79
  • 1
  • 9

1 Answers1

1

So indeed Singleton feels odd at many places, see here as a point to begin reading about it. But then considerable arguments are also made in reply. Perhaps in short, the bottom line is brought here, i.e. that Singleton is a good idea only if you have a single shared resource that should be managed. So if the resource in question has to have no more that one instance representation, and this instance is to be responsible for managing this resource, then Singleton is probably the way to go.

Now, your Parameters and Consts classes does not seem (in lack of additional info) like they need to be managed. Moreover, using Singleton just so you can access its interface globally in the system is not a good idea. That's because you very quickly loose track of where in the system its being relied upon (what parts depend on it), and so any future changes to it will potentially cause hard-to-anticipate bugs and artifacts.

Is there any reason not to make just a single instance of Consts and then pass it around to whomever needs it -- thus exposing the dependency instead of hiding it?

For example, foo() could be defined like this:

void foo(const Consts& consts) {
    Matrix a = consts._k;
    int b = consts._params.x;
}

Or your OtherClass class could receive it in its CTor and store it as a member for its methods to access:

class OtherClass {
private:
    const Consts& mConsts;

public:
    OtherClass(const Consts& consts)
    : mConsts(consts)
    {}

    void foo() {
        Matrix a = mConsts._k;
        int b = mConsts._params.x;
    }
}
Geezer
  • 5,339
  • 14
  • 28
  • its geeting complex because im using Qt, and i want this class to be used int moveToThread, and for that i need to do registerMetaClass and the class have to be with constructor without parameters – asaf anter Aug 23 '18 at 14:49
  • @asafanter Well i'll have to dust off my QT skills to go over what your saying, but in the meantime how about the first option I gave with `void foo(const Consts& consts)`? – Geezer Aug 23 '18 at 14:51
  • i think i will use it but it feel awkward to pass Consts to all the constructors of my classes – asaf anter Aug 23 '18 at 17:49
  • Well, I can only try to help you find what's the right solution for you. Regarding the disadvantages of global data I already gave my account, which as you can see in the links is pretty much accepted with the vast majority of the community. Maybe it'll help you feel less awkward if you treat this like any other data structure, holding stuff you need to access only in some places. As being const is just a particular case of this genera idea. – Geezer Aug 23 '18 at 18:16
  • You can read some very general info here regarding this: https://en.wikipedia.org/wiki/Dependency_injection. Namely that "the intent behind dependency injection is to decouple objects to the extent that no client code has to be changed simply because an object it depends on needs to be changed to a different one." – Geezer Aug 23 '18 at 18:21