tags:

views:

436

answers:

4

Hi

Sorry for reposting this, but for some reason I can not add comments to my older post. Some people wanted to know the exact error message I get when trying to do the following:

I have probably a quite simple problem but I did not find a proper design decision yet. Basically, I have 4 different inherited classes and each of those classes has more than 10 methods.

Each of those classes should make use of the same TCP Socket; this object keeps a socket open to the server throughout program execution. My idea was to have the TCP obejct declared as "global" so that all other classes can use it:

 classTCP TCPSocket;

 class classA
 {
 private:
 public:
 classA();
 virtual void method1();
 ...

 };

class classB
{
 private:
 public:
 classB();
 virtual void method1();
  ...

};

and so on for classC and classD...

Unfortunately, when declaring it like this my Symbian GCC-E compiler gives me the following error message

elf2e32 : Error: E1027: ELF File contains initialized writable data.

So I am wondering if there is any other way I could declare this TCP object so that it is available for ALL the other classes and its methods? classA() is the first method that will be called when initialising this subsystem.

Many thanks!

A: 

A Singleton pattern.

Gregory Mostizky
Note that it is not thread-safe by default.
nagul
and that it has the fun side effect of preventing you from ever creating more than one socket, which I doubt he's interested in. Say after me: "Singletons are not drop-in replacements for globals".
jalf
@jalf: I am not sure I understand your point. Singletons don't prevent you from having more than one object. For example SocketManager.createNewSocket()...
Gregory Mostizky
+1  A: 

There is very elegant way to retrieve static instances on demand.

classTCP& SingletonInstance()
{
    static classTCP instance;
    return instance;
}

Idea is using c++ feature to initialize local static variables only on demand.

Dewfy
the only problem to be aware of with this is potential race conditions when the function is first called, and two threads try to initialize your classTCP simultaneously.
jalf
not a problem using volatile keyword.
Dewfy
A: 

You can support a class-wide static member by allowing both classA and classB to inherit from the same parent.

class BaseTCP {
   static classTCP tcp;
   // ...
};

class classA : BaseTCP {
   // ...
};

class classB : BaseTCP {
   // ...
};

Now classA and ClassB both share the same static member. The stipulation is that you now have to declare the static member outside of the BaseTCP class someplace, similar to:

classTCP BaseTCP::tcp;

Depending on your situation, this may be overkill...

ezpz
A: 

Instead of using singletons, why don't you just create a classTCP instance and pass references to the other objects, each of which owns a reference (or pointer) to the single instance of classTCP.

This offers a much more flexible design - I think singletons generally suck and have much more limited use that generally believed. If you use a singleton, your classes classA, classB etc... have no option but to use the singleton instance. Using a more standard object composition design, you free the whole thing up.

Ask yourself questions like, what if I want the application to talk to >1 server? or what if I want to write some unit test code for classA? Writing unit test code for networking applications is a lot easier when you don't need to use real sockets but can use dummy ones that simply hold the chunks of data in ram. Add a comment if you want an example, because I'm off for lunch now:)

Doing it the way I suggest does not add significant complexity to the overall design but makes it much more open.

Steg