我正在开发一个小程序。我使用Qt作为GUI。我有2个表格/课程。 MainWindow
和AddProductDialog
。
我需要一个变量(确切地说std::string
)。我需要在AddProductDialog
的事件中定义它(例如std::string decl = ""
;)并且我需要在我的MainWindow的函数中使用它的值。
我以为我可以将这个变量放在一个头文件中,每个头文件都会包含但显然它不起作用。
现在它有效,但我认为这不是一个好的风格。我在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";
答案 0 :(得分:5)
在我的指南中,严格禁止在实现文件中使用extern声明。在功能块或命名空间范围内。
Externs必须出现在客户端和定义它的文件的.h文件中。这样可以更容易地发现类型或属性的差异。当您将冗余限制为单个实例时,还可以更轻松地进行维护。
答案 1 :(得分:4)
我不确定我是否理解你的问题,但是你不能只是让descr成为addproductdialog的私有成员,一旦对话结束并被接受,主窗口有一个getter来读取它吗?
答案 2 :(得分:1)
您将头文件和相应的源文件视为实现某些功能的模块。按照惯例,您将它们命名为相似,例 MainWindow.h 和 MainWindow.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 时,它首先将其视为extern声明,然后获得实际定义。这根本不是问题,也没有必要像编译单元特定的定义那样摆弄预处理器结构。
我不知道变量descr
如何与程序中的所有代码相关。您将找到更好的文件名称。因此,我故意选择一个丑陋的文件名来鼓励使用更好的文件名。
答案 3 :(得分:0)
此:
descr = "whatever";
必须位于函数内或定义函数的初始值设定项中。
我会将extern std::string descr;
放在头文件中。定义可以在您认为“属于”的任何地方进行。
答案 4 :(得分:-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文件中定义。在所有其他人中被淹没。