Используя побитовые операторы для булевских переменных в C++

для этого нам нужно знать три компонента

  1. место, ответственное за firing the Event
  2. место, ответственное за responding to the Event
  3. Само событие a. Событие b .EventArgs c. Событие EventArgs enumeration

теперь позволяет создавать событие, которое запускается при вызове функции

, но мой порядок решения этой проблемы выглядит следующим образом: я использую класс до того, как я создайте его

  1. место, ответственное за responding to the Event
    NetLog.OnMessageFired += delegate(object o, MessageEventArgs args) 
    {
            // when the Event Happened I want to Update the UI
            // this is WPF Window (WPF Project)  
            this.Dispatcher.Invoke(() =>
            {
                LabelFileName.Content = args.ItemUri;
                LabelOperation.Content = args.Operation;
                LabelStatus.Content = args.Status;
            });
    };
    

NetLog - это статический класс, который я объясню позже

следующим шагом будет

  1. место, ответственное за firing the Event
    //this is the sender object, MessageEventArgs Is a class I want to create it  and Operation and Status are Event enums
    NetLog.FireMessage(this, new MessageEventArgs("File1.txt", Operation.Download, Status.Started));
    downloadFile = service.DownloadFile(item.Uri);
    NetLog.FireMessage(this, new MessageEventArgs("File1.txt", Operation.Download, Status.Finished));
    

на третьем шаге

  1. Событие self

Я исказил Событие в классе NetLog

public sealed class NetLog
{
    public delegate void MessageEventHandler(object sender, MessageEventArgs args);

    public static event MessageEventHandler OnMessageFired;
    public static void FireMessage(Object obj,MessageEventArgs eventArgs)
    {
        if (OnMessageFired != null)
        {
            OnMessageFired(obj, eventArgs);
        }
    }
}

public class MessageEventArgs : EventArgs
{
    public string ItemUri { get; private set; }
    public Operation Operation { get; private set; }
    public Status Status { get; private set; }

    public MessageEventArgs(string itemUri, Operation operation, Status status)
    {
        ItemUri = itemUri;
        Operation = operation;
        Status = status;
    }
}

public enum Operation
{
    Upload,Download
}

public enum Status
{
    Started,Finished
}

, теперь этот класс содержит the Event, EventArgs и EventArgs Enums и the function ответственный за обстрел события

извините за этот длинный ответ

71
задан Coding Mash 1 September 2012 в 22:59
поделиться

7 ответов

|| и && булевы операторы, и встроенные, как гарантируют, возвратятся или true или false. Ничто иное.

|, & и ^ побитовые операторы. Когда домен чисел, на которые Вы воздействуете, равняется всего 1 и 0, тогда они - точно то же, но в случаях, где Ваши булевские переменные не являются строго 1 и 0 – как имеет место с языком C – можно закончить с некоторым поведением, которое Вы не хотели. Например:

BOOL two = 2;
BOOL one = 1;
BOOL and = two & one;   //and = 0
BOOL cand = two && one; //cand = 1

В C++, однако, эти bool тип, как гарантируют, будет только или true или false (которые преобразовывают неявно в соответственно 1 и 0), таким образом, это - меньше беспокойства от этой позиции, но то, что люди не привыкли к наблюдению таких вещей в коде, приводит хороший аргумент в пользу того, что он не сделал его. Просто скажите b = b && x и быть сделанными с ним.

51
ответ дан Cheers and hth. - Alf 24 November 2019 в 13:04
поделиться

Две главных причины. Короче говоря, рассмотрите тщательно; могло быть серьезное основание для него, но если существует быть ОЧЕНЬ явным в Ваших комментариях, потому что это может быть хрупким и, поскольку Вы говорите, что себя, люди обычно не привыкли к наблюдению кода как это.

Поразрядный xor! = Логический xor (за исключением 0 и 1)

Во-первых, если Вы воздействуете на значения кроме false и true (или 0 и 1, как целые числа), ^ оператор, может представить поведение, не эквивалентное логическому xor. Например:

int one = 1;
int two = 2;

// bitwise xor
if (one ^ two)
{
  // executes because expression = 3 and any non-zero integer evaluates to true
}

// logical xor; more correctly would be coded as
//   if (bool(one) != bool(two))
// but spelled out to be explicit in the context of the problem
if ((one && !two) || (!one && two))
{
  // does not execute b/c expression = ((true && false) || (false && true))
  // which evaluates to false
}

Кредит пользователю @Patrick для выражения этого сначала.

Порядок операций

1118-секундный, |, &, и ^, как побитовые операторы, не закорачивают. Кроме того, несколько побитовых операторов, объединенных в цепочку вместе в отдельном операторе - даже с явными круглыми скобками - могут быть переупорядочены оптимизирующими компиляторами, потому что все 3 операции являются обычно коммутативными. Это важно, если порядок операций имеет значение.

, Другими словами

bool result = true;
result = result && a() && b();
// will not call a() if result false, will not call b() if result or a() false

будет не всегда давать тот же результат (или конечное состояние) как [1 120]

bool result = true;
result &= (a() & b());
// a() and b() both will be called, but not necessarily in that order in an
// optimizing compiler

, Это особенно важно, потому что Вы не можете методы управления a() и b(), или кто-то еще может приехать и изменить их позже не понимание зависимости и вызвать противное (и только часто сборка конечных версий) ошибка.

27
ответ дан Patrick Johnmeyer 24 November 2019 в 13:04
поделиться

Я думаю

a != b

, то, что Вы хотите

11
ответ дан Mark Borgerding 24 November 2019 в 13:04
поделиться

Повышенные брови должны сказать Вам достаточно прекращать делать его. Вы не пишете код для компилятора, Вы пишете его для своих коллег - программистов сначала и затем для компилятора. Даже если компиляторы работают, удивление других людей не то, что Вы хотите - побитовые операторы для битовых операций не для bools.
я предполагаю, что Вы также едите яблоки с ветвлением? Это работает, но это удивляет людей, таким образом, лучше не сделать это.

10
ответ дан kokos 24 November 2019 в 13:04
поделиться

Вопреки ответу Patrick C++ не имеет никакого ^^ оператор для выполнения эксклюзивного замыкания накоротко или. Если бы Вы думаете об этом в течение секунды, имея ^^, оператор не имел бы смысла так или иначе: с эксклюзивным или, результат всегда зависит от обоих операндов. Однако предупреждение Patrick о не - bool "булевы" типы содержит одинаково хорошо при сравнении 1 & 2 к 1 && 2. Одним классическим примером этого является функция Windows GetMessage() , которая возвращает с тремя состояниями BOOL: ненулевой, 0, или -1.

Используя & вместо [1 110] и | вместо [1 112] не редкая опечатка, поэтому если Вы сознательно делаете ее, она заслуживает комментария, говорящего почему.

3
ответ дан bk1e 24 November 2019 в 13:04
поделиться

Patrick сделал правильные замечания, и я не собираюсь повторять их. Однако мог бы я предлагать уменьшить 'если' операторы до читаемого английского языка по мере возможности при помощи хорошо названного булева Вара. Например, и это использует булевы операторы, но Вы могли одинаково использовать поразрядно и назвать bools соответственно:

bool onlyAIsTrue = (a && !b); // you could use bitwise XOR here
bool onlyBIsTrue = (b && !a); // and not need this second line
if (onlyAIsTrue || onlyBIsTrue)
{
 .. stuff ..
}

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

  • Ваш код легче понять, потому что промежуточная булевская переменная для, 'если' условие делает намерение условия более явным.
  • , Если Вы используете нестандартный или неожиданный код, такой как побитовые операторы на булевых значениях, люди могут намного более легко видеть, почему Вы сделали это.

РЕДАКТИРОВАНИЕ: Вы явно не сказали желание условных выражений для того, 'если' операторы (хотя это кажется наиболее вероятным), который был моим предположением. Но мое предложение промежуточного булева значения все еще стоит.

2
ответ дан genix 24 November 2019 в 13:04
поделиться

IIRC, много компиляторов C++ предупредят при попытке бросить результат битовой операции как bool. Необходимо было бы использовать бросок типа для создания компилятора счастливым.

Используя битовую операцию в, если выражение обслуживало бы ту же критику, хотя, возможно, не компилятором. Любое ненулевое значение считают верным, таким образом, что-то как "если (7 & 3)" будет верно. Это поведение может быть приемлемым в Perl, но C/C++ является очень явными языками. Я думаю, что бровь Spock является должной осмотрительностью.:) Я добавил бы "== 0" или"! = 0 дюймов для создания его совершенно ясным, какова цель была.

, Но так или иначе, это походит на персональное предпочтение. Я выполнил бы код через линт или подобный инструмент и видел бы, думает ли это также, что это - неблагоразумная стратегия. Лично, это читает как ошибка кодирования.

0
ответ дан spoulson 24 November 2019 в 13:04
поделиться
Другие вопросы по тегам:

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