用 C++ 构建一个不需要 class 实例化的库
Build a library in C++ which does not require class instantiation
抱歉,如果这似乎是一个初学者问题,但我似乎无法为我的 C++ 库找出最佳方法。我已经构建了一个静态库,其中包含驱动程序 API 处理代码。目前,为了在软件的更高层(带有 GUI 的简单应用程序)中使用它,我需要将 link 库添加到项目中并创建一个 class 的新实例,该实例存在于此库以访问其所有 public 方法。创建此 class 的新实例时,将初始化代码工作所需的所有必要对象。我想跳过实例化步骤,让潜在用户仅通过在他们的代码中包含库来让它工作。为了更好地描述这一点,这里有一个代码示例:
我目前拥有的:
#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 class 的实例。我从下面的评论中获得了很多知识,并将单例响应标记为有效,因为如果可能的话,这将是我继续进行的方式。
假设你有这个:
#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();
函数局部 static myLib
将在第一次调用该方法时初始化。
但是,您可能还想在代码的其他地方使用 MyLib
实例并将其包装在 startProcess
中并不是一个真正的选择。您宁愿使用不受欢迎的单例模式。这是关于 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
被初始化。
抱歉,如果这似乎是一个初学者问题,但我似乎无法为我的 C++ 库找出最佳方法。我已经构建了一个静态库,其中包含驱动程序 API 处理代码。目前,为了在软件的更高层(带有 GUI 的简单应用程序)中使用它,我需要将 link 库添加到项目中并创建一个 class 的新实例,该实例存在于此库以访问其所有 public 方法。创建此 class 的新实例时,将初始化代码工作所需的所有必要对象。我想跳过实例化步骤,让潜在用户仅通过在他们的代码中包含库来让它工作。为了更好地描述这一点,这里有一个代码示例:
我目前拥有的:
#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 class 的实例。我从下面的评论中获得了很多知识,并将单例响应标记为有效,因为如果可能的话,这将是我继续进行的方式。
假设你有这个:
#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();
函数局部 static myLib
将在第一次调用该方法时初始化。
但是,您可能还想在代码的其他地方使用 MyLib
实例并将其包装在 startProcess
中并不是一个真正的选择。您宁愿使用不受欢迎的单例模式。这是关于 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
被初始化。