Reputation: 2238
I'm developing a small progran. I use Qt for the GUI. I have 2 Forms / Classes. MainWindow
and AddProductDialog
.
There is a variable (a std::string
to be exact) which I need in both of them. I need to define it in an Event of AddProductDialog
(e.g. std::string decl = ""
;) and I need to use the value of it in a function of my MainWindow.
I thought I could place this variable in a header file which each of them will include but apparently it doesn't work.
Now it works but I don't think that's a good style. I declared and defined it in my 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);
}
This works of course. But is there a way to declare this variable in a header and include it so I can use it?
I tried something like this at first but it always caused an error :
header
//include guard
extern std::string descr;
//include guard
mainwindow
//include header
//...
std::string descr = "";
//...
addproductdialog
//include header
//...
extern std::string descr;
descr = "whatever";
Upvotes: 2
Views: 221
Reputation: 13690
You treat the header file and the corresponding source file as a module that implements somethings. Per convention you name them similar, e.g. MainWindow.h and MainWindow.cpp.
You should add an extern declaration in the header file for each variable that is defined in that module and shall be public visible to other modules. Every module that needs to know the type or the instance name of the variable just includes the required header file. Or course the implemention source includes its own header file.
Example:
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
The variable addProductDialog
is defined extern
in the header file. When the compiler processes the compilation unit MainWindow.cpp it first "sees" it as extern declaration later it gets the actual definition. That's no problem at all and there is no need to fiddle with preprocessor constructs like compilation unit specific defines.
I don't know how the variable descr
is related to all the code in your program. You will find a better names for the files. Therefore I choosed intentionally an ugly file name to encourage to use a better one.
Upvotes: 1
Reputation: 17163
In my guidelines you're strictly forbidden to use extern declaration in an implementation file. Either in function block or namespace scope.
Externs must appear in a .h file that is included by client and the file that defines it. That makes it easier to discover discrepancy in type or attributes. Also allows easier maintenance, as you limit redundancy to a single instance.
Upvotes: 5
Reputation: 14039
You can do this.
In the header file
/* header.h */
MYEXTERN std::string descr;
In main.cpp
/* MYEXTERN doesn't evaluate to anything, so var gets defined here */
#define MYEXTERN
#include "header.h"
In the other .cpp files
/* MYEXTERN evaluates to extern, so var gets externed in all other CPP files */
#define MYEXTERN extern
#include "header.h"
So it gets defined in only one .cpp file & gets externed in all the others.
Upvotes: -1
Reputation: 129374
This:
descr = "whatever";
must be within a function or as an initializer where the function is defined.
And I would put the extern std::string descr;
in a header file. The definition can go wherever you feel it "belongs".
Upvotes: 0
Reputation: 1021
I'm not sure I understand your problem very well, but couldn't you just make descr a private member of addproductdialog, have a getter for the mainwindow to read it once the dialog ends and is accepted?
Upvotes: 4