News:

This week IPhone 15 Pro winner is karn
You can be too a winner! Become the top poster of the week and win valuable prizes.  More details are You are not allowed to view links. Register or Login 

Main Menu

C++ tips - Managing single instance classes

Started by ben2ong2, October 07, 2006, 09:49:29 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ben2ong2

PROBLEM: You are not allowed to view links. Register or Login (Robert Schmidt)

I find C++ to be of great value when it comes to modelling various
elements of a program, be it simulations of real life things, or more
abstract concepts like data structures.

I have one minor problem though.  I'm modelling the input devices of my
software in C++, and since there is only one Keyboard, one Mouse, one Gamecard
etc, I want to prohibit that several instances can be created of these
classes.  I see two possible solutions, but don't particularly fancy any
of them:

RESPONSE: You are not allowed to view links. Register or Login (Robert Fries)

I don't understand why you feel that creation of several instances of these
classes must be prohibited. Any instantiation would have to be done
explicitly. Just don't do it twice.

And I didn't understand what felt wrong about using global objects
for these devices. They are GLOBAL resources, available to, and needed
by, much of the program. This sounds like one of the valid
uses for global objects.

RESPONSE: You are not allowed to view links. Register or Login (Steve Vinoski), 16 Nov 93

Instead of thinking in terms of global variables, think of global
resources that can be accessed via local class instances:

void foo()
{
    Keyboard k;
    if (k.some_operation()) {
        ...
    }
    ...
}

The "globalness" of the keyboard is hidden in the Keyboard class via a
static pointer to the "real" Keyboard:

class RealKeyboard;   // can be hidden in implementation file

class Keyboard
{
  public:
    Keyboard() {if (kbd == 0) kbd = new RealKeyboard;}

    int some_operation() {return kbd->some_operation();}

    // details omitted

  private:
    static RealKeyboard *kbd;
};

(Given the forward decl of RealKeyboard, I realize that neither the
Keyboard ctor nor some_operation() would compile as shown; I only
wrote them this way for the sake of brevity.)

This arrangement ensures that a single instance of RealKeyboard gets
set up when required, and only a single instance is ever created
regardless of the number of instances of the Keyboard resource handle
class that are created to access it.  The RealKeyboard class can be
fully declared and defined within the implementation file to prevent
clients from using it directly (alternatively it could be forward
declared within the Keyboard class and fully declared and defined in
the impl file, if your compiler supports the new "forward declaration
of nested classes" feature (which cfront 3.0.2 appears to handle
correctly)).

This approach comes in quite handy for multi-threaded code since mutex
locking of global resources can be hidden inside the resource handle
classes, i.e., no need to deal with a global variable and a separate
yet related global mutex.

Naturally, there are other ways to write the resource handle class,
e.g., a reference-counting scheme.


[ We use the RealKeyboard method in handling translations of user
  keystrokes into editing meta-codes in ob and wb. -adc ]


You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login