There is a task from different parts of the program to send data to the output in Gui (and also to have access to the settings). Singleton is the best solution for this. But when using, some kind of stupid error comes up during signal emission, it seems to have done everything correctly, classically:

class QLogger : public QObject { Q_OBJECT public: static const QLogger * instance(); static void logger(const QString &str); static void setEnableLogging(bool stat); static inline bool isLoggingEnabled(){return self->enable;} signals: void doSend(const QString &str); private: static QChatLogger *self; QLogger(QObject * parent = 0); Q_DISABLE_COPY(QLogger) bool enable; }; //================================ QChatLogger *QChatLogger::self = 0; QLogger::QLogger(QObject *parent) : QObject(parent) { self = this; self->enable = true; } const QLogger *QLogger::instance() { static QLogger logger; return &logger; } void QLogger::logger(const QString &str) { if (self->isLoggingEnabled ()) emit self->doSend(str); } void QLogger::setEnableLogging(bool stat) { self->enable = stat; } 

Oh yes. Mistake:

 src/qlogger.cpp: In static member function 'static void QLogger::logger(const QString&)': src/qlogger.cpp:19:50: error: passing 'const QLogger' as 'this' argument of 'void QLogger::doSend(const QString&)' discards qualifiers [-fpermissive] 

UPD: Updated the code, it is fully working. Happy Coding!

  • And yet, there is not enough blocking of simultaneous access to the enable property. After all, this logger will be called from different threads, which means there is a very high probability of “racing” when reading and writing, which is fraught with indefinite behavior of the logger. - vladimir_ki

2 answers 2

The error is that

 static const QLogger * instance(); 

Returns ptr to a constant object, so its modifications will be invalid. In general, in a singleton, it is enough to have only one static method for accessing an instance, and the remaining methods should be non-static. If the goal is to prevent the user from removing the singleton, then you can return a link to QLogger instead of a pointer.

And also: it is necessary to ensure the thread safety of the methods, since going to use it in a multithreaded environment.

  • Duck in C ++ 0x all singletones are thread-safe. - ReklatsMasters 2:01 pm
  • As for initialization, yes, right. But no one guarantees thread-safe access, for example, to a member of the enable class from different threads: while one writes, the other can read, and then the result will be unpredictable. - vladimir_ki
  • You are right, the probe was in the const modifier. I myself do not understand why I wrote. Now a few undefined reference to `QLogger :: enable 'has come out. Wherever it is used - with or without an object ... - ReklatsMasters
  • Remove the "static" from all methods and class members, and QLogger::instance() function static and do not change its contents. Then the work of all methods is much easier. - vladimir_ki

Get a private pointer to a class object inside a class and work with it, and not with QLogger :: instance () inside the class methods, should help. Pattern Singleton

  • Whether inside a class there will be a static object, or inside a function, it does not matter in this case, since The problem is precisely in the const qualifier. - vladimir_ki
  • Those. If I create a private pointer to an object of the QClass class in the QClass class, will there be any problems? It's safe? What could be the pitfalls? - Robotex
  • It seems to be quite, although here @vladimir_ki is right and the point is in const. And the pitfalls - I honestly do not know, with ++ the main language, but I would pay attention to thread safety when creating this static object - aknew
  • one
    When creating a problem with the "race" will not, because this is guaranteed by the standard, but when sharing data already created a static object - can be. To avoid this, you need to take specials. measures, for example, critical sections, in singleton methods. - vladimir_ki