bool "панель" по умолчанию верен, но это должна быть ложь, это не может быть initiliazied в конструкторе. существует ли путь к init это как ложь, не делая это статичным?
Упрощенная версия кода:
foo.h
class Foo{
public:
void Foo();
private:
bool bar;
}
foo.c
Foo::Foo()
{
if(bar)
{
doSomethink();
}
}
На самом деле, по умолчанию он вообще не инициализируется. Значение, которое вы видите, - это просто некоторые значения мусора в памяти, которые использовались для распределения.
Если вы хотите установить значение по умолчанию, вам нужно будет задать его в конструкторе:
class Foo{
public:
Foo() : bar() {} // default bool value == false
// OR to be clear:
Foo() : bar( false ) {}
void foo();
private:
bool bar;
}
Обновление C ++ 11:
Если вы можете использовать компилятор C ++ 11, вы можете сейчас Конструкция по умолчанию вместо (большую часть времени):
class Foo{
public:
// The constructor will be generated automatically, except if you need to write it yourself.
void foo();
private:
bool bar = false; // Always false by default at construction, except if you change it manually in a constructor's initializer list.
}
Попробуйте:
class Foo
{
public:
void Foo();
private:
bool bar;
}
Foo::Foo() : bar(false)
{
if(bar)
{
doSomething();
}
}
Вы можете инициализировать любую переменную, когда вы ее объявляете.
bool bar = 0;
Другой вариант мог бы быть создать TThread, который выполняет управление таймером:
type
TestThreadMsg = class(tThread)
private
fTargetDate : tDateTime;
fMsg : Cardinal;
protected
procedure Execute; override;
procedure NotifyApp;
public
constructor Create( TargetDate : TDateTime; Msg:Cardinal);
end;
реализация:
constructor TestThreadMsg.Create(TargetDate: TDateTime; Msg: Cardinal);
begin
inherited Create(True);
FreeOnTerminate := true;
fTargetDate := TargetDate;
fMsg := Msg;
Suspended := false;
end;
procedure TestThreadMsg.Execute;
begin
Repeat
if Terminated then exit;
if Now >= fTargetDate then
begin
Synchronize(NotifyApp);
exit;
end;
Sleep(1000); // sleep for 1 second, resoultion = seconds
Until false;
end;
procedure TestThreadMsg.NotifyApp;
begin
SendMessage(Application.MainForm.Handle,fMsg,0,0);
end;
Который затем можно подключить к основной форме:
const
WM_TestTime = WM_USER + 1;
TForm1 = Class(TForm)
:
procedure FormCreate(Sender: TObject);
procedure WMTestTime(var Msg:tMessage); message WM_TestTime;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TestThreadMsg.Create(IncSecond(Now,5),WM_TestTime);
end;
procedure TForm1.WMTestTime(var Msg: tMessage);
begin
ShowMessage('Event from Thread');
end;
-121--3509317- Чтобы выяснить, что люди говорят о DoEvents, вот описание того, что может произойти.
Предположим, что у вас есть форма с данными о ней, и ваше продолжительное событие сохраняет ее в базе данных или создает на ее основе отчет. Вы начинаете сохранять или генерировать отчет, а затем периодически вызываете DoEvents, чтобы экран продолжал рисовать.
К сожалению, экран не только картина, но и реагирует на действия пользователя. Это происходит потому, что DoEvents останавливает то, что вы делаете сейчас для обработки всех сообщений Windows, ожидающих обработки приложением Winforms. Эти сообщения включают запросы на перерисовку, а также любой пользователь, набирающий, щелкающий и т.д.
Так, например, во время сохранения данных пользователь может выполнять такие действия, как создание модального диалогового окна приложения, которое полностью не связано с длительной выполняемой задачей (например, Справка - > О программе). Теперь вы реагируете на новые действия пользователя внутри уже выполняющейся длинной задачи. DoEvents будет возвращен, когда все события, которые ожидали, когда вы его вызвали, будут завершены, а затем ваша долгая задача будет продолжена.
Что делать, если пользователь не закрывает модальный диалог? Ваша долгая задача будет ждать вечно, пока это диалоговое окно не будет закрыто. Если вы принимаете на себя обязательства в отношении базы данных и держите в руках транзакцию, то теперь вы держите транзакцию открытой, пока у пользователя есть кофе. Время ожидания транзакции истекает, и вы теряете работу по сохранению, или транзакция не истекает, и вы потенциально блокируете других пользователей базы данных.
Здесь происходит то, что Application.DoEvents делает ваш код повторным. См. определение википедии здесь . Обратите внимание на некоторые точки из верхней части статьи, что для повторного ввода кода:
Маловероятно, что длинный код в приложении WinForms работает только с данными, передаваемыми в метод вызывающей стороной, не содержит статических данных, не содержит блокировок и вызывает только другие методы.
Как говорят многие люди, DoEvents может привести к очень странным сценариям в коде. Ошибки, к которым это может привести может быть очень трудно диагностировать, и ваш пользователь вряд ли скажет вам «О, это могло произойти, потому что я нажал эту несвязанную кнопку, пока я ожидал ее сохранения».
-121--3236074-Ответ Клаима является точечным. Для «решения» проблемы можно использовать список инициализации конструктора . Я настоятельно рекомендую вам прочитать эту страницу, поскольку она может прояснить некоторые подобные вопросы, которые у вас могут возникнуть в будущем.
Лично я предпочитаю видеть видео на чем-то вроде Vimeo, а не на YouTube или подобном сайте. У Vimeo есть определенный воздух профессионализма по этому поводу, хотя все еще быть удобным и удобным для пользователя. Кроме того, вы можете размещать внедренные видео на своих страницах поддержки, если хотите, или просто ссылаться на видео в часто задаваемых вопросах или на форумах. Это делает его очень удобным. Опять же, это просто MHO.
-121--3329833-C/C + + вообще не инициализируют переменные. Ячейка памяти, которая сейчас используется штангой, имела в ней значение, которое интерпретируется как «истина». Так будет не всегда. Необходимо инициализировать его в конструкторе.
-121--1699271- Эта программа имеет неопределенное поведение. Внутренние типы не имеют конструкторов. Можно выполнить bool bar = bool ();
, но лучше определить фактическое значение в классе foo.
Другой вариант мог бы быть создать TThread, который выполняет управление таймером:
type
TestThreadMsg = class(tThread)
private
fTargetDate : tDateTime;
fMsg : Cardinal;
protected
procedure Execute; override;
procedure NotifyApp;
public
constructor Create( TargetDate : TDateTime; Msg:Cardinal);
end;
реализация:
constructor TestThreadMsg.Create(TargetDate: TDateTime; Msg: Cardinal);
begin
inherited Create(True);
FreeOnTerminate := true;
fTargetDate := TargetDate;
fMsg := Msg;
Suspended := false;
end;
procedure TestThreadMsg.Execute;
begin
Repeat
if Terminated then exit;
if Now >= fTargetDate then
begin
Synchronize(NotifyApp);
exit;
end;
Sleep(1000); // sleep for 1 second, resoultion = seconds
Until false;
end;
procedure TestThreadMsg.NotifyApp;
begin
SendMessage(Application.MainForm.Handle,fMsg,0,0);
end;
Который затем можно подключить к основной форме:
const
WM_TestTime = WM_USER + 1;
TForm1 = Class(TForm)
:
procedure FormCreate(Sender: TObject);
procedure WMTestTime(var Msg:tMessage); message WM_TestTime;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TestThreadMsg.Create(IncSecond(Now,5),WM_TestTime);
end;
procedure TForm1.WMTestTime(var Msg: tMessage);
begin
ShowMessage('Event from Thread');
end;
-121--3509317- Чтобы выяснить, что люди говорят о DoEvents, вот описание того, что может произойти.
Предположим, что у вас есть форма с данными о ней, и ваше продолжительное событие сохраняет ее в базе данных или создает на ее основе отчет. Вы начинаете сохранять или генерировать отчет, а затем периодически вызываете DoEvents, чтобы экран продолжал рисовать.
К сожалению, экран не только картина, но и реагирует на действия пользователя. Это происходит потому, что DoEvents останавливает то, что вы делаете сейчас для обработки всех сообщений Windows, ожидающих обработки приложением Winforms. Эти сообщения включают запросы на перерисовку, а также любой пользователь, набирающий, щелкающий и т.д.
Так, например, во время сохранения данных пользователь может выполнять такие действия, как создание модального диалогового окна приложения, которое полностью не связано с длительной выполняемой задачей (например, Справка - > О программе). Теперь вы реагируете на новые действия пользователя внутри уже выполняющейся длинной задачи. DoEvents будет возвращен, когда все события, которые ожидали, когда вы его вызвали, будут завершены, а затем ваша долгая задача будет продолжена.
Что делать, если пользователь не закрывает модальный диалог? Ваша долгая задача будет ждать вечно, пока это диалоговое окно не будет закрыто. Если вы принимаете на себя обязательства в отношении базы данных и держите в руках транзакцию, то теперь вы держите транзакцию открытой, пока у пользователя есть кофе. Время ожидания транзакции истекает, и вы теряете работу по сохранению, или транзакция не истекает, и вы потенциально блокируете других пользователей базы данных.
Здесь происходит то, что Application.DoEvents делает ваш код повторным. См. определение википедии здесь . Обратите внимание на некоторые точки из верхней части статьи, что для повторного ввода кода:
Маловероятно, что длинный код в приложении WinForms работает только с данными, передаваемыми в метод вызывающей стороной, не содержит статических данных, не содержит блокировок и вызывает только другие методы.
Как говорят многие люди, DoEvents может привести к очень странным сценариям в коде. Ошибки, к которым это может привести может быть очень трудно диагностировать, и ваш пользователь вряд ли скажет вам «О, это могло произойти, потому что я нажал эту несвязанную кнопку, пока я ожидал ее сохранения».
-121--3236074-Поскольку вы используете значение bar в столбце, я предполагаю, что вы пытаетесь установить его до создания объекта? Я думаю, вы хотели сделать его статической переменной класса вместо переменной экземпляра.
Если это стандартное приложение WinForms, то все, что вам действительно нужно сделать в приложении, это добавить обработчики событий в форму для DragEnter и DragDrop.
Внутри DragEnter, вы хотите проверить тип объекта, чтобы убедиться, что это имя файла:
private void MyForm_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] files = e.Data.GetData(DataFormats.FileDrop) as string[];
if (files != null)
{
// Do additional checks here if needed, like check extensions
e.Effect = DragDropEffects.Copy;
return;
}
}
e.Effect = DragDropEffects.None;
}
Затем в обработчике DragDrop, я просто сохранить имена файлов, а затем активировать таймер. Это позволяет DragDrop возвращаться немедленно, так что другое приложение (в вашем примере, проводник Windows) не зависает во время обработки файла, которая может занять время. Источник перетаскивания не будет возвращен до завершения DragDrop.
private void MyForm_DragDrop(object sender, DragEventArgs e)
{
string[] files = e.Data.GetData(DataFormats.FileDrop) as string[];
if (files != null)
{
_filesToProcess.Text = files[0]; // Assuming this is declared at the Form level
// Schedule a timer to fire in a few miliseconds as a simple asynchronous method
_DragDropTimer.Interval = 50;
_DragDropTimer.Enabled = true;
_DragDropTimer.Start();
Activate(); // Activates the form and gives it focus
}
}
-121--3418721- Из того, что я понимаю, простая версия такова:
object.to_a
пытается преобразовать «object» в массив с помощью функции class члена. Массив (объект)
пытается создать новый массив с помощью объекта. Я могу заново определить, что .to _
означает для данного класса (это просто другой член в конце концов). Вызов Array (...)
определен в ядре, поэтому он ведет себя одинаково для любого класса. Я обычно использую преобразования типов стиля Array (...)
, когда не знаю заранее, какой тип объекта будет передан. Лучше обрабатывать случаи, когда объект не умеет преобразовывать себя в массив или не может быть преобразован в массив. Если преобразуемый объект является результатом длинного или сложного выражения, использование стиля Array (...)
часто становится более ясным. Я сохраняю форму .to _ формы
для экземпляров, когда я знаю класс объекта и точно, что ожидать от вывода .to _ a
(в основном, для экземпляров, когда я написал или изменил .to _ функцию члена
сам).
C/C + + вообще не инициализируют переменные. Ячейка памяти, которая сейчас используется штангой, имела в ней значение, которое интерпретируется как «истина». Так будет не всегда. Необходимо инициализировать его в конструкторе.