11

I have a class instance that needs to be accessed by some other classes.

  • It would be quite cumbersome to pass the instance always down the construction chain.
  • I tried to avoid global variable, since people tend to advise against this.
  • I thought I declare this instance a static member of a class and then include this class in order to access the instance but this does not work either

error: calling a private constructor of class 'Foo'

To specify the problem further in the context of the QGraphicsView Framework: I want to add QGraphicsItems which are instantiated by a controller class (managing the items) to the QGraphicsScene, which is (but I do not insist on that detail) a member of my QMainWindow class.

I spend a considerable amount of time searching the internet but I am fairly new and am kind of stuck here. I appreciate any incentive on what the best way to solve the dilemma would be.

7
  • 5
    static in a class shares some disadvantages with global variables. The cleanest thing is the "cumbersome" parameter-passing Commented Apr 27, 2015 at 7:45
  • 3
    You should have a look about the Singleton Pattern : en.wikipedia.org/wiki/Singleton_pattern Commented Apr 27, 2015 at 7:50
  • 4
    @Caduchon ...except singletons are disliked because of the same reasons (after all, the usual singleton based on static class variables). Some reading: stackoverflow.com/questions/137975/… etc.etc. Commented Apr 27, 2015 at 7:54
  • 8
    The Singleton pattern is just a glorified global variable. If you see that passing parameters in the constructor is cumbersome it might be time to flatten your dependencies somehow. Commented Apr 27, 2015 at 7:54
  • Hum... That's true. The question is more complex that I thought. Commented Apr 27, 2015 at 7:57

2 Answers 2

2

The use of globals are extremely controversy discussed, that's why I want to point out, that what I write in the following is my personal opinion and open to discussion.

I know no way beside passing instance to resolve your problem without a global object. I personal do not think that a global instance is an evil thing in all situation.

  1. When I design a library I tend to avoid global objects except one factory. Global objects are often used as shortcut where no shortcut is needed or to avoid some typing for the programmer. Also, mostly classes in a library should be independent. You sacrifice independency if you use global instances inside such classes.

  2. When I use statics in a class, I only use them if the whole class is a singleton or for factory methods (e.g. create or get). Never in a way you described. In the way you described it, it is unexpected for other developer, because you need a third party to initialize that static object. You gain nothing with that except avoid typing a longer constructor. This cannot be a goal.

  3. If I use a global instance, I always wrap it in a management class. I never use third party classes like QGraphicsItems direct as globals (also no "primitive" classes or types). Like in point 2, other may not expect that as global. More important it is not clear who has to fill or kill the instance. A "GraphicsItemManager" can have a "setup" method which makes that totally clear to 3rd users.

  4. Passing instances is not in every situation the best way IMHO. Not all my classes are for reuse, they are solely for one project. Here the speed of realization, the ease of use and the clear grouping worth more than a dogma as "no globals". Most time I write manager classes which group instances of e.g. graphic items. I do not have the feeling that makes the code less readable as long I used the rules I pointed out before.

  5. Sometimes a resource is not available by construction time, so you have already pass a wrapper. This leads to a point where you have pass instances through classes which themselves do not need that resource or are themself part of a library (in that case, often you cannot change the constructor). This can (as we are all humans) lead to misinterpretation. I use global management classes to jump over those "gabs", as I think it worth more to keep that space clean from dependencies.

As I wrote IMHO.

Sign up to request clarification or add additional context in comments.

Comments

0

This problem arises when you have a design where class A creates class B which creates class C which needs to accept an instance of class D in its constructor. Then you have to pass D all the way through A, B and C. If you change the design to have a create instances function (either in the main or in some factory class) which knows how to create A, B, C and D. Then you can write this function as follows:

D d; C c(d); B b(c); A a(b); 

This way each class only accepts its dependencies.

If you later realize that B also needs to use class D then you can just change the constructor of B without affecting the constructor of A.

6 Comments

So then a->b->c->d->doSomething(a); ? Whats the difference between this and always passing the pointer to the same istance? D d; C c(d); B b(d); A a(d);
Who is calling doSomething? The class that calls it should hold a D and not an A.
Assuming A is the GraphicsItem to added to the QGraphicsScene D it would look like this: a->d->addItem(a); Or did I missunderstand your example?
The idea is not to have a deep structure but rather have each class only know its own dependencies and not its subclasses dependencies. If a function of class a wants to call a function of class d then it should hold an instance of class d.
No I meant composition. Subclass==instances held by composition.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.