我是C++的新手(之前的Python经验,涉及Java),我正在编写一个小程序作为熟悉项目.作为程序的一部分,我正在编写一个类来解码一些数据,并最终编写一个类似的将执行编码的类.代码是我确定我会经常重用的东西,并认为创建一个库作为项目的一部分会很有趣.我的问题是,什么被认为是创建图书馆的最佳做法?
编辑:(修订)
在提出这个问题之后,我意识到我不知道我不知道的是什么.我做了一些更多的研究,这应该有助于使我的问题更具体:
原始问题:(上下文)
我最初的想法是创建包含MyEncoder和MyDecoder类的MyLib是最方便的.
如果我这样做,我只是在标题中声明这两个类吗?
我想从这个库中创建一个DLL,以实现可移植性和体验.我确信有很多关于创建和使用DLL的信息(这不是这个问题的主题),但是如果有一个特别好的教程(对于Qt)请传递它.
我的假设是,最好为MyEncoder和MyDecoder使用单独的命名空间来实现此实现,而不是MyLib的一个命名空间?
我可以看到这种方法的一个折衷是应用程序的大小,因为包括MyLib.h将包括编码器和解码器的代码(如果编码器和解码器是单独的应用程序).这是假设我没有使用DLL.
我想我得到的是:
如果它更具体,我在Qt Creator中使用Qt 4.7.4进行开发.
关于库,C++中的一个"最佳实践"通常是"你付出的代价".
这适用于您的问题是您将MyEncoder和MyDecoder放在单独的头文件中.因此,如果用户想要使用MyEncoder,他将包含MyEncoder.h,如果他想使用MyDecoder,他将包含MyDecoder.h,如果他想使用两者,他将包括两个头.
链接器通常只包含您在可执行文件中使用的代码部分,因此就代码大小而言,没有任何代价,但编译时间会受到惩罚,特别是如果您在类中开始使用高级模板技术.在大型项目中编译时间可能会很长,因此只能包含您要使用的内容非常重要.
当然,有时候用一个标题包含所有内容也很方便.所以你可以拥有的是:
然后MyCodec.h可以包含MyEncoder.h和MyDecoder.h
假设它们意味着对相同类型的数据进行操作,可能没有充分的理由将MyEncoder和MyDecoder放在不同的命名空间中.
您可能希望拥有类似MyCodec命名空间的东西,并在该命名空间中声明MyEncoder和MyDecoder.
更新了您的修订版:
作为一个库,我的假设是,要添加MyEncoder,我只需创建另一个类/头文件.
这是一个正确的假设.
接下来发生的事情是我不确定的地方.我只是建立图书馆吗?我的理解是它将创建(在Windows中).lib和.h文件.在这一步之前我应该做些什么吗?是否存在会影响我与之互动方式的选项?
我有一段时间没有使用过Qt创建者,所以我不能在权限上说话或者如何访问相关选项.但作为一般规则,您将需要至少有两个版本的库; 调试版本和发布版本.如果您的库使用Qt库,那么当应用程序链接到库的调试版本时,他们需要在其路径中具有Qt共享库的调试版本,如果它们链接到您的发行版本,则需要拥有Qt库的发布版本.
您可能还有一些选项可以静态链接到C++标准运行时库,还是动态链接到DLL.
但基本上是的,您只需构建库,然后使用它的应用程序将库链接到可执行文件.
我只是在我的程序中包含该头文件来访问我写的两个类吗?
您包含头文件,并链接到.lib文件.这就是你应该做的一切.
这适用于 Qt Creator 2.4.1。
首先,要使用和调试您的库,您需要有一个带有两个子项目的分层顶层项目:一个用于库,另一个用于使用它的应用程序。这样,创作者将重建一切,改变其运行的应用程序之前-因此如果你改变了库的源文件,该库将得到自动重建以及应用程序将得到重新连接。
我将逐步展示如何创建所需的三个项目(库、应用程序和顶级项目),最终得到一个可构建、可调试的最小应用程序和库。您可以按照相同的步骤轻松添加更多子库。
为您的项目创建一个文件夹。
热门项目
File->New File or Project, Other Project, Subdirs Project, Choosetop并将其放在您在步骤 1 中创建的文件夹中。库项目 - 新项目窗口出现在上一步的点击中。
Other Project, C++ Library, Chooselibrary并将其放在top上一步创建的文件夹中。默认情况下,您应该已经选择了该文件夹。应用程序项目 - 右键单击top“项目”窗格中的项目(不是在 top.pro 上)
Qt Widget Project, Qt Gui Application, Chooseapp并将其放在top步骤 2 中创建的文件夹中。默认情况下应该已经为您选择了该文件夹。您现在应该有一个可构建的top项目,它具有app和library作为子项目。按 CB(Ctrl-B 或 Command-B,取决于您的平台)来构建它。构建应该没有错误地通过。
该app子项目不使用我们的图书馆呢。要app与我们的图书馆建立链接:
app在 Projects 窗格中右键单击(不是在 app.pro 上),选择Add Library...
选择Internal Library,继续
library是唯一的选择,并已选择。点击到最后。该app项目现在与library. 更改app项目中的任何文件(可以更改空格)以强制构建,然后按 CB 进行构建。构建应该通过 OK。
的app,如果库是改变子项目将被重建,但并没有什么保证的化妆系统将先建库子项目,开始构建应用程序之前。此类信息属于顶级top.pro项目文件。
打开top.pro,并添加一行CONFIG += ordered。该文件应如下所示:
TEMPLATE = subdirs
SUBDIRS += \
library \
app
CONFIG += ordered
Run Code Online (Sandbox Code Playgroud)
确保 SUBDIRS 的顺序正确:库在应用程序之前。如果顺序错误,您可以将条目重新排列为正确的顺序。反斜杠\是换行符。后面不能有空格\!
保存文件 (CS),右键单击top项目并选择“重建项目”“顶部”。构建应该没有错误地完成。警告没问题。
在 Qt Creator 的左下角面板中,有一个带有构建按钮(锤子)、运行按钮(三角形)、调试按钮(带有 bug 的三角形)、构建选择器(带有top项目的笔记本电脑)的面板上面的名称,并省略下面的构建配置。单击构建选择器,并确保您选择以 结尾的构建Debug。此构建配置为生成在调试器下运行所需的调试符号。我们稍后将需要它在。
我们现在将向 Qt Creator 为我们创建的 Library 类添加一些代码。打开library.h和library.cpp文件。添加的代码只是 Library 类中的一个静态方法。该方法将在 App 中使用,以显示这两个部分实际上已链接。两个文件的内容如下。
//library.h
#ifndef LIBRARY_H
#define LIBRARY_H
#include <QString>
class Library {
public:
Library();
static QString string();
};
#endif // LIBRARY_H
Run Code Online (Sandbox Code Playgroud)
//library.cpp
#include "library.h"
Library::Library()
{}
QString Library::string()
{
return "I come from the library";
}
Run Code Online (Sandbox Code Playgroud)
点击 CB,代码应该可以无误地重建。
现在让我们使用app. 打开mainwindow.cpp和mainwindow.h文件并修改如下。
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QScopedPointer>
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
QScopedPointer<Ui::MainWindow> const ui;
};
#endif // MAINWINDOW_H
Run Code Online (Sandbox Code Playgroud)
//mainwindow.cpp
#include <QVBoxLayout>
#include <QLabel>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "library.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QVBoxLayout * layout = new QVBoxLayout();
QLabel * label = new QLabel(Library::string(), centralWidget());
layout->addWidget(label);
centralWidget()->setLayout(layout);
}
MainWindow::~MainWindow()
{}
Run Code Online (Sandbox Code Playgroud)
点击 CB,项目应该可以构建。
然后我们可以在Library::string()实现中设置一个断点,以查看不仅调用了代码,而且调试器可以跨子项目工作。在 中library.cpp,单击行中行号左侧的灰色区域return "I come from the library";。您单击的位置将出现一个带有小沙漏的红色圆圈:这意味着已经设置了一个挂起的断点。
接下来点击 CY 在调试器中启动项目。唯一可运行的子项目是应用程序,它将被自动选为启动项目。
最终,当调试器读取符号文件并找出断点的位置时,断点圆将失去沙漏。此后不久,代码将在 Library::string() 方法中停止——它是从 MainWindow 构造函数调用的。点击 CY 继续执行app.
现在将出现主窗口,其中的I come from the library文本可见。此文本设置在添加到 MainWindow 构造函数中的标签上。
| 归档时间: |
|
| 查看次数: |
4296 次 |
| 最近记录: |