Почему является C++ bool var, верным по умолчанию?

bool "панель" по умолчанию верен, но это должна быть ложь, это не может быть initiliazied в конструкторе. существует ли путь к init это как ложь, не делая это статичным?

Упрощенная версия кода:

foo.h

class Foo{
 public:
     void Foo();
private:
     bool bar;
}

foo.c

Foo::Foo()
{  
   if(bar)
   {
     doSomethink();
   }
}
17
задан user 5 April 2012 в 14:04
поделиться

7 ответов

На самом деле, по умолчанию он вообще не инициализируется. Значение, которое вы видите, - это просто некоторые значения мусора в памяти, которые использовались для распределения.

Если вы хотите установить значение по умолчанию, вам нужно будет задать его в конструкторе:

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.
}
64
ответ дан 30 November 2019 в 10:06
поделиться

Попробуйте:

class Foo
{ 
  public: 
    void Foo(); 
  private: 
     bool bar; 
} 

Foo::Foo() : bar(false)
{
  if(bar) 
  { 
    doSomething(); 
  }
}
0
ответ дан 30 November 2019 в 10:06
поделиться

Вы можете инициализировать любую переменную, когда вы ее объявляете.

bool bar = 0;
-1
ответ дан 30 November 2019 в 10:06
поделиться

Другой вариант мог бы быть создать 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-

Ответ Клаима является точечным. Для «решения» проблемы можно использовать список инициализации конструктора . Я настоятельно рекомендую вам прочитать эту страницу, поскольку она может прояснить некоторые подобные вопросы, которые у вас могут возникнуть в будущем.

5
ответ дан 30 November 2019 в 10:06
поделиться

Лично я предпочитаю видеть видео на чем-то вроде Vimeo, а не на YouTube или подобном сайте. У Vimeo есть определенный воздух профессионализма по этому поводу, хотя все еще быть удобным и удобным для пользователя. Кроме того, вы можете размещать внедренные видео на своих страницах поддержки, если хотите, или просто ссылаться на видео в часто задаваемых вопросах или на форумах. Это делает его очень удобным. Опять же, это просто MHO.

-121--3329833-

C/C + + вообще не инициализируют переменные. Ячейка памяти, которая сейчас используется штангой, имела в ней значение, которое интерпретируется как «истина». Так будет не всегда. Необходимо инициализировать его в конструкторе.

-121--1699271-

Эта программа имеет неопределенное поведение. Внутренние типы не имеют конструкторов. Можно выполнить bool bar = bool (); , но лучше определить фактическое значение в классе foo.

2
ответ дан 30 November 2019 в 10:06
поделиться

Другой вариант мог бы быть создать 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 в столбце, я предполагаю, что вы пытаетесь установить его до создания объекта? Я думаю, вы хотели сделать его статической переменной класса вместо переменной экземпляра.

0
ответ дан 30 November 2019 в 10:06
поделиться

Если это стандартное приложение 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 _ функцию члена сам).

-121--4605415-

C/C + + вообще не инициализируют переменные. Ячейка памяти, которая сейчас используется штангой, имела в ней значение, которое интерпретируется как «истина». Так будет не всегда. Необходимо инициализировать его в конструкторе.

1
ответ дан 30 November 2019 в 10:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: