【问题标题】:Build a library in C++ which does not require class instantiation用 C++ 构建一个不需要类实例化的库
【发布时间】:2021-01-22 20:56:27
【问题描述】:

抱歉,这似乎是一个初学者问题,但我似乎无法为我的 C++ 库找到最佳方法。我已经构建了一个静态库,其中包含驱动程序 API 处理代码。目前,为了在软件的更高层(带有 GUI 的简单应用程序)中使用它,我需要将库链接到项目并创建该库中存在的类的新实例以访问其所有公共方法.当创建此类的新实例时,将初始化代码工作所需的所有必要对象。我想跳过实例化步骤,让潜在用户仅通过在他们的代码中包含库来使其工作。为了更好地描绘这一点,这里有一个代码示例:

我目前拥有的:

#include "myLibrary.h"

// Some GUI code here

MyLibrary *mLib;
mLib = new MyLibrary;

// Using the library methods
mLib->startProcess();

我想要什么:

#include "myLibrary.h"

MyLibrary::startProcess();

我在 Qt Creator 中工作,但不介意迁移到不同的 IDE(Visual Studio 也可以)。我在这个项目中的文件是:

  • MyLibrary.h(声明)
  • MyLibrary_global.h(由 Qt Creator 创建的包含列表和导出设置)
  • MyLibrary.cpp(实现)

任何帮助将不胜感激。如果需要进一步澄清我的问题,我将编辑此问题以使其清楚。

编辑:在深入研究驱动程序 API 文档后,我发现它的实现方式需要我创建 MyLibrary 类的实例。我从下面的 cmets 获得了很多知识,并将单例响应标记为有效,因为如果可能的话,这将是我继续进行的方式。

【问题讨论】:

  • 您的教科书、教程或课程是否提到了静态成员函数?
  • 不相关,但在这种情况下使用指针和new 似乎没有任何作用。只需MyLibrary myLib; myLib.startProcess();
  • 一开始就有上课的理由吗?
  • 嗯...这不就是你梦想场景中的命名空间语法吗?
  • @AlexanderMayer namespace 的“问题”是任何人都可以向他们添加成员。

标签: c++ dependencies qt-creator project


【解决方案1】:

假设你有这个:

#include "myLibrary.h"

// Some GUI code here

MyLibrary *mLib;
mLib = new MyLibrary;

// Using the library methods
mLib->startProcess();

您的库可以像这样隐藏MyLibrary 对象:

startProcess() {
    static MyLibrary* myLib = new MyLibrary;
    myLib->startProcess();
}

这样用户代码看起来像这样:

#include "myLibrary.h"

MyLibrary::startProcess();

函数 local static myLib 将在第一次调用该方法时被初始化。

但是,您可能还想在代码中的其他地方使用 MyLib 实例并将其包装在 startProcess 中并不是一个真正的选择。您宁愿使用对 Singleton Pattern 的不满。这是一个关于 Meyers Singleton 的问答:Is Meyers' implementation of the Singleton pattern thread safe?

我不会详细介绍,因为单例模式在整个网络上都有很好的文档记录。仅概述粗略的想法,这将允许您获得所需的用户代码(未经测试):

struct MyLibrary {
     static void startProcess() {
         instance().doStartProcess();
     }
     private:

     MyLibrary() = default;          // private constructor
     MyLibrary(MyLibrary&) = delete; // no copies
     static MyLibrary& instance() {
          static MyLibrary myLib;              // the actual instance
          return myLib;
     }
     void doStartProcess(){
          // actual implementation
     }
}

注意实际实例myLib是延迟初始化的,即只有第一次调用instance()时,函数local static myLib才被初始化。

【讨论】:

  • 我可能在主应用程序中需要一个 MyLib 实例 - 最重要的是,这必须初始化驱动程序连接并调整我正在使用的设备的一些参数。不知道这是否是个好习惯,但也许我可以在 GUI 应用程序的 Main(或 Qt 的 MainWindow)中初始化第一个调用?
  • @szumial 了解单例模式,这将回答您的问题。不要被对这种模式的抱怨所迷惑。它可以被滥用,它可以被使用。
  • 我在另一个项目中使用它来处理数据库连接。虽然我在互联网上看到了多个线程警告它。
  • @szumial 它是一个易于批评的模式,因为它与全局变量密切相关(单例是一个全局变量,掩盖了已知的缺点),并且因为关注“只有一个实例” ,但后者在很大程度上只是抱怨锤子不是螺丝的错误工具
  • 那么访问库中的其他方法怎么样?我需要将它们全部设为静态吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
  • 1970-01-01
  • 1970-01-01
  • 2013-08-15
  • 2012-08-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多