I have a file that I want to declare in a main, but modify in a thread.
I declare in my MainWindow
header file std::ofstream file;
.
Then I try to initialize it my constructor of my MainWindow.cpp
like this : file("test.txt", std::ios::out | std::ios::trunc);
The function in the thread is static:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Constructs the new thread and runs it. Does not block execution.
ref_bool_Server = true;
fichier ("test.txt", std::ios::out | std::ios::trunc);
m_t1 = std::thread(lancerServeur, std::ref(ref_bool_Server), std::ref(lancerEnregistrement));
// Je sauvegarde ma main window
m_psMainWindow = this;
}
MainWindow::~MainWindow()
{
delete ui;
ref_bool_Server = false;
m_t1.join();
}
void MainWindow::lancerServeur(std::atomic<bool>& boolServer, std::atomic<bool>& lancerEnregistrement){
serveur s;//J'instancie un serveur
StructureSupervision::T_StructureSupervision* bufferStructureRecu;
while(boolServer){
bufferStructureRecu = s.receiveDataUDP();
if(bufferStructureRecu != NULL){
m_psMainWindow->emit_signal_TrameRecu( bufferStructureRecu );
}
if(lancerEnregistrement){
fichier << bufferStructureRecu->SystemData._statutGroundFlight;
}
}
}
The de claration of the ofstream is false (probably synthaxic), and I don't know how to use this file in a static function.
Technically speaking, you can't call a constructor, at least
not in the sense you mean. (An expression such as
std::ofstream( "test.txt" )
looks like you're calling
a constructor, but the standard calls it an explicit type
conversion.) The constructor is called when you define
a variable, e.g. in the statement std::ofstream file;
(which
calls the default constructor). When you write file(...)
, the
compiler looks for an overloaded operator()
in the type of
file
; there isn't one, so it is an error.
It's not clear what you actually want to do, so it's difficult
to provide exact advice. One thing is sure, however: you do
not want a definition of a variable (e.g.
std::ofstream file;
at namespace scope) in a header. If you
do, that header can only be included in one source, or you'll
end up with multiple definitions. (Such a definition would be
reasonable in a class definition in a header.) At best, you
would want extern std::ofstream file;
in the header, with the
definition in one (and only one) of the source files which
include that header; in the definition, you can provide
arguments which would be used for construction. Except that
I can't think of a context where it would make sense to have an
std::ofstream
at namespace scope.
EDIT:
From your update of the question, from the error message, it
looks like file
is a member variable. In that case, you
provide any arguments to the constructor in the initializer list
of the constructor:
MainWindow::MainWindow()
: file( "test.txt" )
{
}
And of course, if it is a member, you cannot access it without having an instance of the class. Which is not normally the case in a static member function.
EDIT:
After your update: it's still not clear whether you want
fichier
to be a static member or not. Typically, there will
be only one MainWindow
object; do both users have access to
it? (This would normally be the preferred solution.) If so,
there's no problem making it non-static, and initializing it as
above. Or you could pass a reference to it (the fichier
member) directly to the thread. This is the solution I would
prefer. Alternatively, you could declare it static. In that
case, you would need to explicitly define it in one, and only
one source file:
std::ofstream MainWindow::fichier;
And you would then open it in the constructor:
fichier.open( "test.txt" );
This could cause problems, however, if more than one instance of
MainWindow
gets constructed.
Finally, from the code you show: only the thread actually uses
the file, so it might be preferrable to declaring it as a local
variable in the lancerServer
function. There's no point in
making it visible to several threads if only one is going to
access it. If this is due to a simplification in your posted
code, and it is used by several threads, then you'll need to
add code to synchronize access.