views:

97

answers:

2

Hello,

Currently I'm using singleton pattern for certain global objects in my application (Qt application for Symbian environment). However, because of some problems (http://stackoverflow.com/questions/3147375/c-checking-singleton-pointers/3147806#3147806) it looks like that I have to change the logic.

I have 3 classes (logger, settings and container for some temp data) that I need to access via multiple different objects. Currently they are all created using singleton pattern. The logger basically is just one public method Log() with some internal logic when the settings and container have multiple get/set methods with some additional logic (e.g. QFileSystemWatcher). In addition, logger and settings have some cross-reference (e.g. logger needs some settings and settings logs errors).

Currently everything is "working fine", but there is still some problems that should be taken care of and it seems like they are not easy to implement for the singletons (possible memory leaks/null pointers). Now I have two different ways to handle this:

  1. Create global objects (e.g. extern Logger log;) and initialize them on application startup.
  2. Create objects in my main object and pass them to the children as a reference.

How I have few questions related to these:

Case 1.

  • Is it better to use stack or heap?
  • I'm going to declare those objects in some globals.h header using extern keyword. Is it ok?
  • I think in this case I have to remove that 2-way reference (settings needs logger and vice versa.)?

Case 2.

  • Should the objects be created in stack or heap in my main object (e.g. Logger *log = new Logger() vs Logger log;)

  • Long reference chains do not look nice (e.g. if i have to pass the object over multiple childrens).

  • What about in children?

    1. If I pass a pointer to the children like this (I don't want to copy it, just use the "reference"): Children(Logger *log) : m_Log(log) what happens when the children is deleted? Should I set the local pointer m_Log to NULL or?
    2. If I use stack I'll send reference to the child (Children(Logger &log) : m_Log(log)) where m_Log is a reference variable (Logger& m_Log;) right?
  • What should I note in terms of Qt memory management in this case?

Case 3. Continue with singleton and initialize singleton objects during the startup (that would solve the null pointers). Then the only problem would possible memory leaks. My implementation follows this example. Is there a possible memory leak when I'm accessing the class using. What about singleton destruction? #define LOG Logger::Instance()->Log

Thanks for reading.

A: 

Summary in simple terms:

  1. if you use global objects, prefer the singleton pattern as a lesser evil. Note that a singleton should have global access! Dan-O's solution is not really a singleton pattern and it defeats the power of singletons even though he suggests it's no different.
  2. if you use global objects, use lazy construction to avoid initialization order problems (initialize them when they are first accessed).
  3. if you use singletons, instead of making everything that needs to be globally acccessible a singleton, consider making one singleton (Application) which stores the other globally-accessible objects (Logger, Settings, etc.) but don't make these objects singletons.
  4. if you use locals, consider #3 anyway to avoid having to pass so many things around your system.

[Edit] I made a mistake and misplaced the static in safe_static which Dan pointed out. Thanks to him for that. I was blind for a moment and didn't realize the mistake based on the questions he was asking which lead to a most awkward situation. I tried to explain the lazy construction (aka lazy loading) behavior of singletons and he did not follow that I made a mistake and I still didn't realize I made one until the next day. I'm not interested in argument, only providing the best advice, but I must suggest strongly against some of the advice, particularly this case:

#include "log.h"

// declare your logger class here in the cpp file:
class Logger
{
// ... your impl as a singleton
}

void Log( const char* data )
{
    Logger.getInstance().DoRealLog( data );
}

If you are going to go with globally accessible objects like singletons, then at least avoid this! It may have appealing syntax for the client, but it goes against a lot of the issues that singletons try to mitigate. You want a publicly accessible singleton instance and if you create a Log function like this, you want to pass your singleton instance to it. There are many reasons for this, but here is just one scenario: you might want to create separate Logger singletons with a common interface (error logger vs. warning logger vs. user message logger, e.g.). This method does not allow the client to choose and make use of a common logging interface. It also forces the singleton instance to be retrieved each time you log something, which makes it so that if you ever decide to steer away from singletons, there will be that much more code to rewrite.

Create global objects (e.g. extern Logger log;) and initialize them on application startup.

Try to avoid this at all costs for user-defined types, at least. Giving the object external linkage means that your logger will be constructed prior to the main entry point, and if it depends on any other global data like it, there's no guarantee about initialization order (your Logger could be accessing uninitialized objects).

Instead, consider this approach where access is initialization:

Logger& safe_static()
{
    static Logger logger;
    return logger;
}

Or in your case:

// Logger::instance is a static method
Logger& Logger::instance()
{
    static Logger logger;
    return logger;
}

In this function, the logger will not be created until the safe_static method is called. If you apply this to all similar data, you don't have to worry about initialization order since initialization order will follow the access pattern.

Note that despite its name, it isn't uber safe. This is still prone to thread-related problems if two threads concurrently call safe_static for the first time at the same time. One way to avoid this is to call these methods at the beginning of your application so that the data is guaranteed to be initialized post startup.

Create objects in my main object and pass them to the children as a reference.

It might become cumbersome and increase code size significantly to pass multiple objects around this way. Consider consolidating those objects into a single aggregate which has all the contextual data necessary.

Is it better to use stack or heap?

From a general standpoint, if your data is small and can fit comfortably in the stack, the stack is generally preferable. Stack allocation/deallocation is super fast (just incrementing/decrementing a stack register) and doesn't have any problems with thread contention.

However, since you are asking this specifically with respect to global objects, the stack doesn't make much sense. Perhaps you're asking whether you should use the heap or the data segment. The latter is fine for many cases and doesn't suffer from memory leak problems.

I'm going to declare those objects in some globals.h header using extern keyword. Is it ok?

No. @see safe_static above.

I think in this case I have to remove that 2-way reference (settings needs logger and vice versa.)?

It's always good to try to eliminate circular dependencies from your code, but if you can't, @see safe_static.

If I pass a pointer to the children like this (I don't want to copy it, just use the "reference"): Children(Logger *log) : m_Log(log) what happens when the children is deleted? Should I set the local pointer m_Log to NULL or?

There's no need to do this. I'm assuming the memory management for the logger is not dealt with in the child. If you want a more robust solution, you can use boost::shared_ptr and reference counting to manage the logger's lifetime.

If I use stack I'll send reference to the child (Children(Logger &log) : m_Log(log)) where m_Log is a reference variable (Logger& m_Log;) right?

You can pass by reference regardless of whether you use the stack or heap. However, storing pointers as members over references has the benefit that the compiler can generate a meaningful assignment operator (if applicable) in cases where it's desired but you don't need to explicitly define one yourself.

Case 3. Continue with singleton and initialize singleton objects during the startup (that would solve the null pointers). Then the only problem would possible memory leaks. My implementation follows this example. Is there a possible memory leak when I'm accessing the class using. What about singleton destruction?

Use boost::scoped_ptr or just store your classes as static objects inside an accessor function, like in safe_static above.

Thanks for the reply. I think I'll try to go with the safe_static way. Now I'm wondering how to apply this approach to my solution. I'll call it on the startup to avoid access problems. How I'm able to transfer that reference to multiple objects (e.g. if I want only one instance of the object)?Can you provide any links/sources which use this kind of approach?
itsme1
@itsme1: nothing fancy, just pass them to functions if you avoid the global approach. If you pass it to a class, you can pass it to its constructor and just store it as a member to avoid the subsequent need to pass it around to the class methods. It's really up to you how you pass these local objects around if you're avoiding globals.
@stinky472: So briefly, I'll add that method call as static to my main class. Then I call it on startup and store the result as a reference to the main. After that I'll just have to pass reference to that object stored in main to all children who needs it.So what is the difference of having that method vs. declaring the object "normally" in main .h/.cpp? And also for me it seems that if you call that safe_static() twice I have 2 instances of the logger?
itsme1
@itsme1 the method doesn't have to be a static method in a class, it could just be a free function (depending on your needs). The method is also if you want to go with the global option (case #1), not case #2. If you're going with case #2, just create the logger directly in the main function. "that if you call that safe_static() twice I have 2 instances of the logger?" No, function-level statics are initialized once upon the first time calling the function only.
What the heck am I missing here... you declare a logger on the stack and return a reference to it? Good luck with that.
Dan O
@Dan it's a global and therefore evil, but this is a form of enforcing an "access is initialization" strategy and a common way of implementing singletons. The logger in the above function will be created when safe_static is called, and no sooner, thus it does not have initialization order problems leading to undefined behavior which is common when one has a bunch of global objects of user-defined types.
The function is global, but that Logger you declared is most certainly not.
Dan O
@Dan global is a relative term and must be used in context. If we're talking about scope, Logger is only accessible inside of safe_static. If we're talking about lifetime, Logger will be created when safe_static is first called and exist for the duration of the process. If we're talking about this from a high-level perspective and considering what states are accessible, if the safe_static is global, then the logger object is globally accessible [through the safe_static function/method]
@Dan Anyway, once you learn about things like singletons, this will make sense to you. It's a form of lazy construction.
Did you meanstatic Logger return logger;}?
Dan O
@Dan Yes. We most commonly see this lazy construction method used in singletons like this: Singleton* Singleton::instance() {static Singleton inst; return } Other people use the heap on a static pointer defined at file scope (this includes static members). Singleton* Singleton::instance() {if (!ptr) ptr = new Singleton; return ptr;} This latter one is a memory leak unless the singleton is manually cleaned up.
Dan O
@Dan not quite. These are not local function variables on the stack. When declared with the *static* keyword, it makes it so that they are generally stored in the data segment, just like a variable declared at file scope, only the data gets initialized after the function has been called for the first time. That *static* keyword makes all the difference in these functions, otherwise it would be unsafe as it would be returning a temporary by reference as you pointed out (but not applicable here). This is not the case with static variables defined in functions.
Ok, I gave you the benefit of the doubt, and now I feel stupid for doing so.Compile the function that you've written it, without the static keyword before the variable declaration, and you will get a warning (warning: reference to local variable 'logger' returned). Please stop arguing this with me, you NEED the static keyword before your variable declaration for this to do what you want it to do... if you were to use this code it would crash or stomp data on stack.The static keyword before a function gives the function file scope, that is all it does.
Dan O
@Dan "Logger return logger; }" yes, that is correct. Apologies for the mistake. static on a function gives it internal linkage, static on a variable inside a function gives causes its state to be retained across all function calls and for it to be initialized on first call to the function.
The version in the comment is what was meant and hopefully now everything I've said is obvious: Singleton* Singleton::instance() {static Singleton inst; return }. Apologies for the confusion, I thought it was clear what was meant (lazy construction) in spite of the mistake I made in the original answer and didn't even notice it the entire time. It has been corrected and now the answer should make a lot more sense - thanks!
And apologies again! I thought you did not understand the static keyword for variables defined in functions and I was trying to explain them the whole time when the whole source of confusion was the hasty error I made in the answer.
A: 

I found the other answer to be a little misleading. Here is mine, hopefully the SO community will determine which answer is better:

Is it better to use the stack or the heap?

Assuming by "the stack" you meant as a global (and thus in the data segment), don't worry about it, do whichever is easier for you. Remember that if you allocate it on the heap you do have to call delete.

I'm going to declare those objects in some globals.h header using extern keyword. Is it ok?

Why do you need to do that? The only classes that need access to the globals are the singletons themselves. The globals can even be static local variables, ala:

class c_Foo
{
    static c_Foo& Instance()
    {
        static c_Foo g_foo; // static local variable will live for full life of the program, but cannot be accessed elsewhere, forcing others to use cFoo::Instance()
        return g_foo;
    }
 };

If you don't want to use the static local then a private static member variable of type c_Foo (in my example) would be more appropriate than a straight global.

Remember, you want the lifetime of the class to be "global" (ie not destroyed until application exit), not the instance itself.

I think in this case I have to remove that 2-way reference (settings needs logger and vice versa.)?

All of the externed globals would have to be forward declared, but as I said above you don't need this header file.

Should the objects be created in stack or heap in my main object (e.g. Logger *log = new Logger() vs Logger log;)

I can't really answer this, don't worry about it again.

Long reference chains do not look nice (e.g. if i have to pass the object over multiple childrens).

What about in children?

Great points, you have realized that this would be a huge pain in the butt. In the case of something like a logger it would be hellish to pass references to every module just so they could spit out logging info. More appropriate would be a single static "Log" function ala C, if your logger has useful state then make it a singleton that is only visible to your log function. You can declare and implement your entire logger class in the same .cpp file that you implement your log function in. Then nothing else will be aware of this special functionality.

Here is what I mean:

file: log.h

#ifndef LOG_H
#define LOG_H

void Log( const char* data ); // or QString or whatever you're passing to your logger

#endif//LOG_H

file: log.cpp

#include "log.h"

// declare your logger class here in the cpp file:
class Logger
{
// ... your impl as a singleton
}

void Log( const char* data )
{
    Logger.getInstance().DoRealLog( data );
}

This is a fine logger interface, all the power of your singleton, limited fuss.

Is there a possible memory leak when I'm accessing the class using. What about singleton destruction?

There is a risk of double instantiation if you're lazily allocating the singleton on the heap in a multithreaded environment. This would cause surplus instances to leak.

There are somewhat similar risks if you use a static local: http://blogs.msdn.com/b/oldnewthing/archive/2004/03/08/85901.aspx

In my opinion explicit construction when execution starts is the best option, but whether it is done in the data segment (with a static variable in a class or global variable) or the heap is very unlikely to matter in your case. If you do allocate it on the heap you should also delete it.

Dan O
Thanks that explains it really well. Also it looks like I'm able to use my current singleton classes with some small modifications.
itsme1
A lot of this is just a revised, dumbed-down copy of my answer with a correction to a mistake which I honestly made but you could not understand that it was a simple mistake even after I explained lazy construction, singletons, etc. You even copied my attempt at correcting itsme1 about data segment vs. stack for what he described as "global objects' and the multithreading caveat to static variables declared in function scope. Boo. You should cite your sources.
You also reduced the already problematic singleton pattern to the worst definition possible. If you're just going to have a global Log function and no public access to the singleton instance it's using as an implementation detail, e.g., then there will be no practical way to ever have more than one logger without major rewrites, no possible chance to use polymorphism, etc. It takes the evilness of singletons and goes a step further.
Interesting, an accepted answer with only downvotes, is there a badge for that?
Philipp
@Philipp There should be!@stinky you can replace your logger at the level of the log function, make it a virtual call or whatever. I'm just pointing out that when a singleton has a single public method it makes more sense to provide access to that single method with a static function. Please don't treat me like an idiot, I am making a valid point here.Problems with your answer: the non static logger, you didn't explain why globals.h was not needed, your answer to the last part is insane.
Dan O
Hehe, looks like this has ended to be a fight between 2 persons. All I wanted to know was a simple answer (if possible) what is the "best" way to make an object which can have its own state and can be accesses from multiple different classes. Currently I'm using the singleton because in my environment (Qt Symbian) it works and provides all I currently need.. However, because I'm not an expert in C++ I wanted to know some recommendation. Currently these answers just make my head more dizzy (thats why I removed the "mistakenly" places answer mark.).
itsme1
Pretty much, I shouldn't have bothered getting involved... His original answer contained a typo he was too proud to acknowledge.
Dan O