c++ - 跨整个项目方法的单例类

标签 c++ multithreading qt oop singleton

我的 Qt 项目中有一个用于日志记录目的的单例类。在除单例类之外的每个类中,都有一个指向单例对象的指针和一个连接到单例对象中的写入槽的信号。无论哪个类想要写入日志信息,只需发出该信号即可。信号已排队,因此是线程安全的。

请从 OOP 的角度批评这种方法,谢谢。

================================================== =============================================== 编辑1: 谢谢大家的申请,听取相反的意见总是一个很大的学习。

让我详细解释一下我的方法以及到目前为止我在代码中所做的事情: 正如 MikeMB 指针一样,单例类有一个静态函数,如 get_instance(),它返回对该单例的引用。我将它存储在每个类的构造函数中的本地指针中,因此构造函数返回后它将被销毁。它可以方便地检查我是否有空指针并使代码更具可读性。我不喜欢这样的东西:

if(mySingletonClass::gerInstance() == NULL) { ... }
connect(gerInstance(), SIGNAL(write(QString)), this, SLOT(write(QString)));

因为它比这个贵:

QPointer<mySingletonClass>  singletonInstance = mySingletonClass::getInstance();
if(singletonInstance.isNull) { ... }
connect(singletonInstance, SIGNAL(write(QString)), this, SLOT(write(QString)));

从 ASM 的角度来看,调用函数两次比创建局部变量更昂贵,因为要计算入栈、出栈和返回地址。

这是我的单例类:

class CSuperLog : public QObject
{
    Q_OBJECT

public:
        // This static function creates its instance on the first call 
        // and returns it's own instance just created
        // It only returns its own instance on the later calls
        static QPointer<CSuperLog> getInstance(void); // 
        ~CSuperLog();

public slots:
    void writingLog(QString aline);

private:
    static bool ready;
    static bool instanceFlag;
    static bool initSuccess;
    static QPointer<CSuperLog> ptrInstance;

    QTextStream * stream;
    QFile * oFile;
    QString logFile;

    explicit CSuperLog(QObject *parent = 0);
};

我在 main() 的开头调用 getInstance(),因此请确保每当其他类需要记录重要信息时立即读取它。

迈克MB:

Your approach is making a middle man sitting in between, it makes the path of the logging info much longer because the signals in Qt are always queued except you make direct connection. The reason why I can't make direct connection here is it make the class non-thread-safe since I use threads in each other classes. Yes, someone will say you can use Mutex, but mutex also creates a queue when more than one thread competing on the same resource. Why don't you use the existing mechanism in Qt instead of making your own?

感谢您的所有帖子!

================================================== =========

编辑2:

致马塞尔·布兰克:

  1. 我也喜欢您的方法,因为您考虑了资源竞争。
  2. 几乎在每个类中,我都需要信号和槽,因此我需要 QObject,这就是我选择 Qt 的原因。
  3. 如果我没有理解错的话,一个静态对象应该只有一个实例。
  4. 使用信号量与使用Qt中的信号/槽相同,都会生成消息队列。
  5. 软件设计模式和应用程序性能总是有利有弊。在中间添加更多层可以使您的代码更加灵活,但会显着降低那些配置较低的硬件上的性能,使您的应用程序依赖于一个最强大的硬件,这就是为什么大多数现代操作系统都是用纯 C 和 ASM 编写的。如何平衡它们确实是一个很大的挑战。

您能否详细解释一下您的静态 Logger 工厂方法?谢谢。

最佳答案

我会考虑将记录器应该是唯一的这一事实与其他类如何获取记录器类的实例分开。

创建和获取记录器实例可以在某种工厂中处理,该工厂内部封装其构造,并在需要时仅创建一个实例。

然后,其他类获取记录器实例的方式可以通过依赖注入(inject)或通过在上述工厂中定义的静态方法来处理。使用依赖注入(inject),您首先创建记录器,然后将其注入(inject)到创建后的其他类中。

关于c++ - 跨整个项目方法的单例类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20174665/

相关文章:

java - 在 Java 中等待条件

c# - 串口通信 : polling serial port vs using serial port DataReceived event

c++ - 无法动态更新 LineSeries QML 类型

c++ - 无法理解零规则中的 C++11 语法

python - pybind11 分区日期时间转换

c++ - 我们是否应该释放为 std::locale 分配的资源

C++ 访问对象,QT

c++ - 语法 - 可能的函数指针

.net - Interlocked.Increment 和返回增量值

c++ - 清理 Qt 布局和添加其他小部件不起作用。幽灵小部件保留。 Qt 错误?