#c #c 11 #fstream
#c #c 11 #fstream
Вопрос:
У меня есть файл, который я хочу объявить в главном, но изменить в потоке.
Я объявляю в своем MainWindow
заголовочном файле std::ofstream file;
.
Затем я пытаюсь инициализировать его своим конструктором my MainWindow.cpp
следующим образом : file("test.txt", std::ios::out | std::ios::trunc);
Функция в потоке статична:
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>amp; boolServer, std::atomic<bool>amp; 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;
}
}
}
Определение ofstream равно false (вероятно, synthaxic), и я не знаю, как использовать этот файл в статической функции.
Комментарии:
1. Не могли бы вы подкинуть нам какой-нибудь код?
2. вы имеете в виду file.open (те же аргументы)? Я думаю, что конструктор принимает только буфер файла, а не те же аргументы, что и file.open
3. @Mayerz Я даю вам все, что есть, там всего 2 строки…
4. Где вы объявляете (или определяете)
file
объект? В глобальном пространстве имен, другом пространстве имен или как член класса?5.
static std::ofstream file;
amp;amp;file = std::ofstream ("test.txt", std::ios::out | std::ios::trunc);
Ответ №1:
Технически говоря, вы не можете вызвать конструктор, по крайней мере, не в том смысле, который вы имеете в виду. (Такое выражение, как std::ofstream( "test.txt" )
выглядит так, как будто вы вызываете конструктор, но стандарт называет это явным преобразованием типов.) Конструктор вызывается, когда вы определяете переменную, например, в инструкции std::ofstream file;
(которая вызывает конструктор по умолчанию). Когда вы пишете file(...)
, компилятор ищет перегруженный operator()
тип file
; его нет, так что это ошибка.
Неясно, что вы на самом деле хотите сделать, поэтому трудно дать точный совет. Однако одно можно сказать наверняка: вам не нужно определение переменной (например, std::ofstream file;
в области пространства имен) в заголовке. Если вы это сделаете, этот заголовок может быть включен только в один источник, иначе в итоге вы получите несколько определений. (Такое определение было бы разумным в определении класса в заголовке.) В лучшем случае вы хотели бы, extern std::ofstream file;
чтобы в заголовке было указано определение в одном (и только одном) из исходных файлов, которые включают этот заголовок; в определении вы можете указать аргументы, которые будут использоваться для построения. За исключением того, что я не могу придумать контекст, в котором имело бы смысл иметь std::ofstream
область пространства имен at.
Редактировать:
Из вашего обновления вопроса, из сообщения об ошибке, похоже, что file
это переменная-член. В этом случае вы предоставляете конструктору любые аргументы в списке инициализаторов конструктора:
MainWindow::MainWindow()
: file( "test.txt" )
{
}
И, конечно, если это участник, вы не сможете получить к нему доступ без
наличие экземпляра класса. Обычно это не так
в статической функции-члене.
Редактировать:
После вашего обновления: все еще не ясно, хотите fichier
ли вы быть статическим участником или нет. Обычно будет только один MainWindow
объект; имеют ли к нему доступ оба пользователя? (Обычно это было бы предпочтительным решением.) Если это так, нет проблем с тем, чтобы сделать его нестатическим и инициализировать его, как указано выше. Или вы могли бы передать ссылку на него ( fichier
элемент) непосредственно в поток. Это решение, которое я бы предпочел. В качестве альтернативы, вы могли бы объявить его статическим. В этом случае вам нужно будет явно определить его в одном и только одном исходном файле:
std::ofstream MainWindow::fichier;
И затем вы бы открыли его в конструкторе:
fichier.open( "test.txt" );
Однако это может вызвать проблемы, если несколько экземпляров
MainWindow
создается.
Наконец, из кода, который вы показываете: файл фактически использует только поток, поэтому это может быть предпочтительнее, чем объявлять его как локальную переменную в lancerServer
функции. Нет смысла делать его видимым для нескольких потоков, если только один собирается получить к нему доступ. Если это связано с упрощением вашего опубликованного кода, и он используется несколькими потоками, тогда вам нужно будет добавить код для синхронизации доступа.
Комментарии:
1. Я обновлю свой пост, чтобы предоставить больше информации, спасибо за вашу помощь.
2. Существует только 1 экземпляр MainWindow, мне нужно объявить свой файл в моем главном, а не локальном на моем сервере, потому что в деструкторе моего основного я хочу удалить файл, если в нем ничего не записано. Я попытаюсь передать экземпляр моего файла таким образом…
3. @EvansBelloeil Все, что вы делаете после объединения, вы могли бы сделать в основной функции потока. Но для удаления не требуется
ofstream
только имя, поэтому вы все равно можете удалить после объединения в главном потоке, даже еслиofstream
объект был в потоке. (Если вы используете Windows, конечно, вам нужно убедиться, что файл закрыт перед удалением.)