Пример C++ Кодирования Ужаса или Блестящей идеи?

Исходя из того же вопроса, который вы задали, вы просто заменили name на true, когда излучаете событие

methods: {
    showModal(name) { this.bus.$emit('showModal', true); },
}

created() {
    // `show` will have the value that you emitted
    this.bus.$on('showModal', (show) => console.log(show);
}
.
12
задан Dan Hewett 22 October 2008 в 17:04
поделиться

17 ответов

Я пошел бы для преступления против кодирования.

Оба метода сгенерируют тот же самый объектный код. Первое делает, это - ясное намерение. Второе очень сбивает с толку с единственным преимуществом, что оно сохраняет пару нажатий клавиш. (Просто учитесь долбаному' типу).

Кроме того, обратите внимание, что НИКАКОЙ метод, как не гарантируют, будет работать. sizeof () объект включает дополнение для выравнивания слов, так, чтобы, если заголовок был:

class Header
{
    int type;
    int payloadLength;
    char  status;
};

Оба метода, которые Вы описываете, имели бы полезную нагрузку, запускающуюся в Header+12, когда, скорее всего, это на самом деле запускается в Header+9.

42
ответ дан 2 December 2019 в 02:50
поделиться

В дополнение к вышеупомянутому я сказал бы, что это - преступление против совместимости и хороших проводных принципов разработки протокола. Действительно удивительно, сколько программисты не способный/желают сделать ясным различием между проводным определением протокола и его реализацией. Если Ваш протокол должен выжить больше двух дней, он по всей вероятности должен выжить больше двух лет/Ose/компиляторов/языков/порядков байтов, и в некоторой точке он повредится, скорее раньше, чем позже. Так, сделайте жизнь других людей легче, запишите проводную спецификацию протокола плюс запись надлежащие (de) стандартные программы сериализации. Иначе люди будут продолжать упоминать Ваше имя в не так приятные контексты.

0
ответ дан 2 December 2019 в 02:50
поделиться

Я голосую за &this[1]. Я видел, что это использовало вполне немного при парсинге файлов, которые были загружены в память (который может одинаково включать полученные пакеты). Это может выглядеть немного нечетным в первый раз, когда Вы видите его, но я думаю, что то, что это означает, должно быть сразу очевидным: это - ясно адрес памяти только мимо этого объекта. Это хорошо, потому что трудно понять превратно.

0
ответ дан 2 December 2019 в 02:50
поделиться

Мне не нравится использовать слова как "преступление". Я указал бы, что &this[1], кажется, делает предположения о расположении памяти, что компилятор мог бы не согласиться с. Например, любой компилятор, по его собственным причинам (как выравнивание), мог бы вставить фиктивные байты где угодно в структуру. Я предпочел бы технику, которая имеет больше гарантии получения корректного смещения, если компиляторы или опции изменяются.

0
ответ дан 2 December 2019 в 02:50
поделиться

Возможно, необходимо ли было использовать подробный метод, но заменить ли его #define макросом? Таким образом, можно использовать стенографию при вводе, но любой бывший должный отлаживать код может следовать вперед без проблемы.

0
ответ дан 2 December 2019 в 02:50
поделиться

Я думаю в этот день и возраст в C++, состав исполнителей C-стиля для обугливания* лишает права Вас на любую "блестящую дизайнерскую идею" премии, не получая большую часть слушания.

Я мог бы пойти для:

#include <stdint.h>
#include <arpa/inet.h>

class Header {
private:
    uint32_t type;
    uint32_t payloadlength;
public:
    uint32_t getType() { return ntohl(type); }
    uint32_t getPayloadLength() { return ntohl(payloadlength); }
};

class Message {
private:
    Header head;
    char payload[1]; /* or maybe std::vector<char>: see below */
public:
    uint32_t getType() { return head.getType(); }
    uint32_t getPayloadLength() { return head.getPayloadLength(); }
    const char *getPayload() { return payload; }
};

Это принимает C99-выход POSIX, конечно: к порту на платформы неPOSIX необходимо было бы определить один или оба из uint32_t и ntohl сами, с точки зрения того, что действительно предлагает платформа. Это обычно не трудно.

В теории Вам, возможно, понадобились бы прагмы расположения в обоих классах. На практике я был бы удивлен, учитывая фактические поля в этом случае. Проблемы можно избежать путем чтения/записи данных из iostreams одно поле за один раз, вместо того, чтобы пытаться создать байты сообщения в памяти и затем записать это сразу. Это также означает, что можно представить полезную нагрузку с чем-то более полезным, чем символ [], который в свою очередь означает, что Вы не должны будете иметь максимального размера сообщения или иметь предосудительные отношения с malloc и/или новым размещением, или что бы то ни было. Конечно, это представляет немного служебное.

1
ответ дан 2 December 2019 в 02:50
поделиться

Я на самом деле делаю что-то подобное, и также - почти каждый MMO или игра онлайн-видео, когда-либо записанная. Хотя у них есть понятие, названное "Пакетом", и каждый пакет имеет свое собственное расположение. Таким образом, Вы могли бы иметь:

struct header
{
    short id;
    short size;
}

struct foo
{
    header hd;
    short hit_points;
}


short get_foo_data(char *packet)
{
    return reinterpret_cast<foo*>(packet)->hit_points;
}

void handle_packet(char *packet)
{
    header *hd = reinterpret_cast<header*>(packet);
    switch(hd->id)
    {
        case FOO_PACKET_ID:
            short val = get_foo_data(packet);
        //snip
    }
}

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

1
ответ дан 2 December 2019 в 02:50
поделиться

Не забывайте, что VC ++ может наложить дополнение на sizeof() значение на классе. Так как обеспеченным примером, как ожидают, составят 8 байтов, это - автоматически выровненный DWORD, быть в порядке - также. Проверить #pragma pack.

Хотя, я соглашаюсь, обеспеченными примерами является определенная степень Кодирования Ужаса. Много структур данных Win32 включают заполнителя указателя в структуру заголовка, когда данные переменной длины следуют. Это - вероятно, самый легкий способ сослаться на эти данные, после того как это загружается в память. MAPI SRowSet структура является одним примером этого подхода.

1
ответ дан 2 December 2019 в 02:50
поделиться

Они - в основном то же самое, что касается меня. Оба - формы манипулирования байта, которое всегда опасно, но не невозможно разобраться. Первая форма немного более принята и распознаваемая. Я лично записал бы:

char* Header::GetPayload()
{
    return ((char*) this) + sizeof(*this);
}
1
ответ дан 2 December 2019 в 02:50
поделиться

Если это работает - последовательно - затем это - изящное решение.

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

Я видел, что это развалилось, когда объекты Заголовка/Полезной нагрузки передаются потоком "по проводу", потому что механизм потоковой передачи, который Вы используете, не будет, вероятно, заботиться о выравнивании объектов ни на какой конкретной границе. Поэтому Полезная нагрузка может непосредственно следовать Заголовку без дополнения для принуждения его к конкретному выравниванию.

Выдумать фразу, изящную, так же изящно, делает. Так, это изящно, пока Вы осторожны, как Вы передаете его потоком.

3
ответ дан 2 December 2019 в 02:50
поделиться

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

Прием должен объявить Вашу структуру как

struct bla {
    int i;
    int j;
    char data[0];
}

Затем участник 'данных' просто указывает на то, что находится позади заголовков. Я не уверен, насколько портативный это; я видел его с '1' как размер массива также.

(использование URL ниже как referece, с помощью' [1]' синтаксис, казалось, не работало, потому что это слишком длинно. Вот ссылка:)

http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/gcc/Zero-Length.html

4
ответ дан 2 December 2019 в 02:50
поделиться

Я думаю, что это испорчено от запуска на том, если заголовок должен "возвратить" данные, которые не включены в него.

Поскольку Вы уже помещаете себя на эту территорию hackish, я действительно люблю то, что Вы придумали.

Но обратите внимание, что это не конкурс красоты. Необходимо найти все другое решение. Для alle три версии GetPayload (), который Вы представили, я не пойму то что, черт возьми, продолжается там без Вашего дальнейшего объяснения.

5
ответ дан 2 December 2019 в 02:50
поделиться

Мой голос Кодирует Ужас. Не понимайте меня превратно, это умно - но Вы сохраняете себя одна вся операция сложения за счет создания кода, намного более трудного понять и читать. Я не рассматриваю компромисса как стоящий того.

5
ответ дан 2 December 2019 в 02:50
поделиться

Это - типичная проблема, но что Вы на самом деле хотите, это.

class Header
{
    int type;
    int payloadLength;
    char payload[0];

};

char* Header::GetPayload()
{
    return payload;
}
13
ответ дан 2 December 2019 в 02:50
поделиться

Вы - в зависимости от компилятора к расположению свои классы конкретным способом. Я определил бы сообщение как структуру (со мной определяющий расположение) и имел класс, который инкапсулирует сообщение и предоставляет интерфейс ему. Код разъединения = хороший код. "Милый" код = плохо (трудно для поддержания) код.

struct Header
{
    int type;
    int payloadlength;
}
struct MessageBuffer
{
   struct Header header;
   char[MAXSIZE] payload;
}

class Message
{
  private:
   MessageBuffer m;

  public:
   Message( MessageBuffer buf ) { m = buf; }

   struct Header GetHeader( )
   {
      return m.header;
   }

   char* GetPayLoad( )
   {
      return &m.payload;
   }
}

Это было некоторое время, так как я записал любой C++, поэтому извините любые проблемы с синтаксисом. Просто пытаясь передать общее представление.

14
ответ дан 2 December 2019 в 02:50
поделиться

Лично я думаю, что, если существует преступление, оно просит у заголовка полезную нагрузку.

Но, пока Вы собираетесь сделать это, тем путем, 'this+1' является столь же хороший путь как любой.

Выравнивание: '&this[1]' является частью общего назначения кода, который не требует, чтобы Вы пошли, роя посредством определений классов, чтобы полностью постигать и не требует фиксации, когда кто-то меняет имя или содержание класса.

BTW, первым примером является настоящее преступление против человечества. Добавьте участника в конец класса, и он перестанет работать. Переместите участников вокруг класса, и он перестанет работать. Если компилятор заполнит класс, то он перестанет работать.

Кроме того, если Вы собираетесь предположить, что расположение компилятора классов/структур соответствует Вашему пакетному расположению, затем необходимо понять, как рассматриваемый компилятор работает. Например, на MSVC Вы, вероятно, захотите знать о #pragma pack.

PS: это немного страшно, сколько людей полагает, что "this+1" или "&this[1]" трудно читают или понимают.

14
ответ дан 2 December 2019 в 02:50
поделиться

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

Является Заголовок хранителем своей Полезной нагрузки?

Это - фундаментальная проблема здесь - и заголовком и полезной нагрузкой должен управлять другой объект, который содержит все сообщение, и это - надлежащее место для просьбы полезную нагрузку. И это смогло бы сделать так без адресной арифметики с указателями или индексации.

Учитывая, что, я одобрил бы второе решение, так как более ясно, что продолжается.

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

Если Вы действительно хотите быть милыми, Вы могли бы сделать вывод.

template<typename T. typename RetType>
RetType JustPast(const T* pHeader)
{
   return reinterpret_cast<RetType>(pHeader + sizeof(T));
}
2
ответ дан 2 December 2019 в 02:50
поделиться
Другие вопросы по тегам:

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