外部变量-我应该把它放在哪里

Extern Variable - where should I place it?

本文关键字:在哪里 我应该 变量 外部      更新时间:2023-10-16

我正在开发一个小程序。我使用Qt作为GUI。我有2个形式/类。MainWindowAddProductDialog

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

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

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

main.cpp:

//includes ...
...
std::string descr; //The variable I need
int main(){ /* blah blah */ }

MainWindow.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
}

AddProduct.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 = "";
//...

addproductdialog

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

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

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

我不确定我很好地理解你的问题,但是你不能让descr成为addproductdialog的一个私有成员,一旦对话框结束并被接受,主窗口就有一个getter来读取它吗?

您将头文件和相应的源文件视为实现某些功能的模块。按照惯例,您可以将它们命名为类似的名称,例如MainWindow.hMainWindow.cpp.

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

的例子:

MainWindow.h

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

AddProduct.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;

main.cpp

#include "MainWindow.h"
#include "AddProduct.h"
#include "SomeCommonDataIDontHaveANameFor.h"
int main(void)
{
    mainWindow.on_AddProductOptions_Clicked();
    addProductDialog.on_CommandOkay_Clicked();
}

MainWindow.cpp

#include "MainWindow.h"
AddProductDialog addProductDialog;
// add implemetation of AddProductDialog class

变量addProductDialog在头文件中定义为extern。当编译器处理编译单元MainWindow.cpp时,它首先将其"视为"外部声明,然后获得实际定义。这完全没有问题,也不需要摆弄预处理器结构,比如编译单元特定的定义。

我不知道变量descr是如何与你程序中的所有代码相关的。您将为这些文件找到更好的名称。因此,我故意选择了一个难看的文件名,鼓励大家使用一个更好的文件名。

This:

 descr = "whatever";

必须在函数中,或者作为定义函数的初始化式。

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

你可以这样做。

在头文件

/* 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文件中定义&