2

我正在开发一个小程序。我将 Qt 用于 GUI。我有 2 个表格/课程。MainWindowAddProductDialog

我在他们两个中都需要一个变量(std::string准确地说是一个)。我需要在AddProductDialog(例如std::string decl = "";)的事件中定义它,并且我需要在我的 MainWindow 的函数中使用它的值。

我想我可以把这个变量放在一个头文件中,每个头文件都会包含,但显然它不起作用。

现在它可以工作了,但我认为这不是一个好的风格。我在 main.cpp 中声明并定义了它。

主.cpp:

//includes ...
...

std::string descr; //The variable I need

int main(){ /* blah blah */ }

主窗口.cpp:

void MainWindow::on_AddProductOptions_clicked()
{
    extern std::string descr;
    AddProductDialog *adp = new AddProductDialog(this);
    adp->setModal(true);

    if(adp->exec() == QDialog::Accepted)
        _Description = descr; //_Description is a private variable of my MainWindow Class
}

添加产品.cpp

void AddProductDialog::on_cmdOkay_clicked()
{
    extern std::string descr;
    descr = "";
    done(QDialog::Accepted);
}

这当然有效。但是有没有办法在头文件中声明这个变量并包含它以便我可以使用它?

起初我尝试过这样的事情,但它总是导致错误:

标题

//include guard
extern std::string descr;
//include guard

主窗口

//include header
//...
std::string descr = "";
//...

添加产品对话框

//include header
//...
extern std::string descr;
descr = "whatever";
4

5 回答 5

5

在我的指导方针中,严禁在实现文件中使用 extern 声明。在功能块或命名空间范围内。

外部变量必须出现在客户端包含的 .h 文件和定义它的文件中。这使得更容易发现类型或属性的差异。还允许更轻松的维护,因为您将冗余限制为单个实例。

于 2013-06-07T17:11:16.793 回答
4

我不确定我是否能很好地理解您的问题,但是您不能让 descr 成为 addproductdialog 的私有成员,让主窗口在对话框结束并被接受后读取它吗?

于 2013-06-07T16:27:04.390 回答
1

您将头文件和相应的源文件视为实现某些东西的模块。根据约定,您将它们命名为相似,例如MainWindow.hMainWindow.cpp

您应该在该模块中定义的每个变量的头文件中添加一个外部声明,并且应该对其他模块公开可见。每个需要知道变量类型或实例名称的模块只包含所需的头文件。或者当然实现源包含它自己的头文件。

例子:

主窗口.h

class MainWindow
{
    public:
        void on_AddProductOptions_clicked();
};

extern MainWindow mainWindow;

添加产品.h

class AddProductDialog 
{
    public:
        void on_CommandOkay_Clicked();
};

extern AddProductDialog addProductDialog;

SomeCommonDataIDontHaveANameFor.h

// If header files should include system header files or not is discussed elsewhere.
// I add this here to allow compiling of the sample code.
#include <string>

extern std::string descr;

SomeCommonDataIDontHaveANameFor.cpp

#include "SomeCommonDataIDontHaveANameFor.h"

std::string descr;

主文件

#include "MainWindow.h"
#include "AddProduct.h"
#include "SomeCommonDataIDontHaveANameFor.h"

int main(void)
{
    mainWindow.on_AddProductOptions_Clicked();
    addProductDialog.on_CommandOkay_Clicked();
}

主窗口.cpp

#include "MainWindow.h"

AddProductDialog addProductDialog;

// add implemetation of AddProductDialog class

该变量在头文件addProductDialog中定义。extern当编译器处理编译单元MainWindow.cpp时,它首先“看到”它作为 extern 声明,然后它得到实际定义。这完全没有问题,也没有必要摆弄诸如编译单元特定定义之类的预处理器结构。

我不知道该变量descr与您程序中的所有代码有何关系。您会找到更好的文件名称。因此,我故意选择了一个丑陋的文件名,以鼓励使用更好的文件名。

于 2013-06-08T10:56:16.210 回答
0

这个:

 descr = "whatever";

必须在函数内或作为定义函数的初始值设定项。

我会把它放在extern std::string descr;一个头文件中。这个定义可以去任何你觉得它“属于”的地方。

于 2013-06-07T16:27:20.527 回答
-1

你可以这样做。

在头文件中

/* header.h */
MYEXTERN std::string descr;

在 main.cpp

/* MYEXTERN doesn't evaluate to anything, so var gets defined here */
#define MYEXTERN 
#include "header.h"

在其他 .cpp 文件中

/* MYEXTERN evaluates to extern, so var gets externed in all other CPP files */
#define MYEXTERN extern
#include "header.h"

所以它只在一个 .cpp 文件中定义,并在所有其他文件中被外部化。

于 2013-06-07T16:29:55.550 回答