We help IT Professionals succeed at work.

Static class, Singleton, or global?

deleyd
deleyd asked
on
352 Views
Last Modified: 2013-12-02
(I come from a C# background, which doesn't translate easily to C++ I've learned.)

State Design Pattern

I have a ClassOne, and in this class it holds another class which is the current state, say classes StandardStateA, StandardStateB.

I also have a ClassTwo, and a ClassThree, which also have a current state class.

There's no reason to have multiple copies of StandardStateA, StandardStateB. The big deal is to be able to easily switch between them.

But static classes don't exist in C++ I'm told. So what other options do I have?

Do I create a global variable instance of StandardStateA, StandardStateB, creating it outside of any class? Or do I go with Singleton? Perhaps I say "forget it" and just go with each class creates its own personal identical copy of StandardStateA and StandardStateB? Is this one of those situations where there is no right answer?
Comment
Watch Question

CERTIFIED EXPERT
Top Expert 2013

Commented:
I am not sure why you refer to your  StandardStateA, StandardStateB as classes. They seem to me more like enum values. I would design the whole thing as:
enum StandardState
{
   StandardStateA,
   StandardStateB
};
class ClassOne
{
public:
   StandardState state;
};
class ClassTwo
{
public:
   StandardState state;
};
class ClassThree
{
public:
   StandardState state;
};

Open in new window

Explanation: enum has only the limited number of values, but I believe you know this anyway. If you are concerned that your StandardState becomes public then you can place it inside a class, like this:
class ClassOne
{
public:
enum StandardState
{
   StandardStateA,
   StandardStateB
};
   StandardState state;
};
class ClassTwo
{
public:
   ClassOne::StandardState state;
};
class ClassThree
{
public:
   ClassOne::StandardState state;
};

Open in new window

BTW, you could have a class consisting of only static members. The class will become static as well, like this:
class ClassA
{
   static void foo();
   static void bar();
}

Open in new window

When you call methods from this class, you do not need to instantiate the actual class object, like this:
void main()
{
   ClassA::foo(); // calling a static member of ClassA
}

Open in new window

deleydSoftware Engineer

Author

Commented:
Well the idea of the State Design Pattern is to have a slot where you can plug in a class.
State currentState;
...
currentState = new StateA;
...
currentState.MethodA;
currentState.MethodB;
...

//later..
currentState = new StateB;

//and we can then go back and call MethodA and MethodB, and we'll get the StateB versions of MethodA and MethodB.

Open in new window

However in this method we always instantiate a new instance of whatever class we want to be the current class. I'm trying to avoid all that creating and destroying.

Aren't enum values just a fancy way to hide integers? Or have they evolved to include classes?
CERTIFIED EXPERT

Commented:
If static class is the one that cannot be instantiated, then you can do the same also in C++. It is only not named that way. Static classes are actually only collection of functions and variables in a separate namespace. You can do the same with plain functions and variables in a C++ namespace. In other words, the need for static classes in C# are the proof that you need sometimes something more than pure OO approach.

Anyway, you can have a static instance of a class in C++, i.e. the one that was not created via new. You can declare it at a global level in a selected .cpp file, and make it available elsewhere via extern in some .h file.

However, there is probably easier, better, and easily understandable imlementation of a singleton pattern in C++. It is called Meyer's singleton -- here is the detailed original aticle by the authors http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf. When using C++11, it is thread safe. It need not to be in older C++. The page http://www.devarticles.com/c/a/Cplusplus/C-plus-plus-In-Theory-The-Singleton-Pattern-Part-I/4/ shows the example implementation for the Log class:
class Log {
public:
  static Log& Instance() {
    static Log theLog;
    return theLog;
}
  void Write(char const *logline);
  bool SaveTo(char const *filename);
private:
  Log();          // ctor is hidden
  Log(Log const&);      // copy ctor is hidden
  Log& operator=(Log const&);  // assign op is hidden

  static std::list<std::string> m_data;
};

Open in new window

trinitrotolueneDirector - Software Engineering

Commented:
I would suggest that you look at the problem not from a programming perspective. What is the problem you are trying to solve?

What are ClassOne, ClassTwo and ClassThree going to be represent and how many objects of them do you need at runtime? How do they interact with each other.?

Will all objects of a particular class exist in the same state? Can objects of different classes exist in the same state?

Let us assume there are only 3 state objects : On, Off and Floating
Also assume there are 5 objects : Class1Obj1, Class2Obj1, Class3Obj1, Class3Obj2, Class2Obj2.

If you create a singleton to represent each of these states then just one object of each of these states is going to exist.

How would you share these 3 state objects amongst the 5 object?


Perhaps you want to create just one state object which changes its internal state value at runtime and which can be accessed and influenced by all the 5 objects.
deleydSoftware Engineer

Author

Commented:
Currently I have "class within a class within a class, within a class."

I have a Controller,

the Controller has a currentMenu

the currentMenu has a currentMenuItem

the currentMenuItem has a currentEventHandler.

There are (currently) two possible currentEventHanders:  one is the regular one that does the same thing for all the menu items on all the menus. I'll call that my StandardEventHandler. Then there's an 'Edit' mode the currentMenuItem can be in, which requires a different set of Event Handlers, I'll call that my EditEventHandler.

There are a dozen menus and each menu has a dozen menu items. But I don't need a dozen squared * 2 event handler class instances, I only need 2.

(The actual names are slightly different, since Visual Studio complains if I try to make a class named 'Menu')

Helpful would be a simple working example of a MenuItemClass
which has a currentEventHandler
and two possible choices for that currentEventHandler
which are StandardEventHandler and EditEventHandler
(both which implement IEventHandler);
designed so I can have a hundred Menu Items,
but not a hundred different Event Handler subclass instances.
CERTIFIED EXPERT

Commented:
What framework do you use? And also, is it to be a native C++ application or the .NET?
deleydSoftware Engineer

Author

Commented:
Native C++. Visual Studio 2010.
deleydSoftware Engineer

Author

Commented:
It occurred to me maybe I needn't be so concerned about instantiating 100 copies of the same class. If all the methods are static I would hope C++ would be smart enough not to make 100 copies, but just have everyone use the same class. Though I'm not sure if that will work in a multithreaded environment.
CERTIFIED EXPERT

Commented:
I suggest to answer (for yourself, and for us) the trinitrotoluene's questions. It really helps to understand what you are solving and whether it should be solved this or that way.

Aren't enum values just a fancy way to hide integers? Or have they evolved to include classes?

Enums came from other languages. Their original intention was to name the otherwise magic numbers, and to add a specific type to the named values. The C-family started with simple "enum value is equal to certain integer". However, the enum type itself could be checked.

C++11 adds stronger type checking where the enum value is not implicitly converted to integer; hence, it cannot be used interchangably with the same integer value. It is defined a enum class name {...}; or enum struct name {...};.

By the way, if you can, switch to Visual Studio 2013. The C++11 is really nice.
CERTIFIED EXPERT
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.