C memset, кажется, не пишет в каждого участника

На самом деле, MST или MobX State Tree - очень описательное имя, если подумать.

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

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

Центральным в MST (mobx-state-tree) является концепция живого дерева. Дерево состоит из изменчивых, но строго защищенных объектов, обогащенных информацией о типе среды выполнения. Другими словами, каждое дерево имеет форму (информация о типе) и состояние (данные). Из этого живого дерева автоматически генерируются неизменные структурно общие снимки.

Однако все это происходит за определенную плату, и MST в целом несколько медленнее, чем чистый MobX. Поэтому, если вам не нужны эти функции, не стесняйтесь использовать только MobX.

6
задан Mizipzor 12 April 2009 в 20:56
поделиться

7 ответов

Нет, не используйте memset - он обнуляет размер указателя (4 байты на моей машине Intel x86) байты, начиная с местоположения, указанного этого . Это плохая привычка: вы также обнуляете виртуальные указатели и указатели на виртуальные базы при использовании memset со сложным классом. Вместо этого сделайте:

template <class T>
class vector2
{
public:
    // use initializer lists
    vector2() : x(0), y(0) {}
    T x;
    T y;
};
25
ответ дан 8 December 2019 в 02:03
поделиться

Как говорят другие, memset () - неправильный способ сделать это. Однако есть некоторые тонкости, почему нет.

Во-первых, ваша попытка использовать memset () очищает только sizeof (void *) байтов. Для вашего примера, это, по-видимому, совпадение с байтами, занятыми членом x .

Простым решением было бы написать memset (this, 0, sizeof (* this)) , который в этом случае установит x и y .

Однако, если ваш класс vector2 имеет какие-либо виртуальные методы, и используется обычный механизм чтобы представить их вашим компилятором, то этот memset уничтожит vtable и сломает экземпляр, установив указатель vtable в NULL. Что плохо

Другая проблема состоит в том, что если для типа T требуется какое-либо более сложное действие конструктора, чем просто установка его битов в 0, тогда конструкторам для элементов не вызывается , но их эффект уничтожается перезаписью содержимого членов с помощью memset () .

Единственное правильное действие - написать конструктор по умолчанию как

vector2(): x(0), y(0), {}

и просто забыть о попытке использовать memset ( ) для этого вообще.

Редактировать: Д.Шоули указал в комментарии, что конструкторы по умолчанию для x и y фактически были вызваны до memset () в исходном коде, как представлено. Хотя это технически верно, вызов memset () перезаписывает членов, что в лучшем случае очень, очень плохо, и в худшем случае вызывает демонов Неопределенного Поведения.

Как написано, класс vector2 является POD, пока тип T также является простыми старыми данными, как было бы в случае если бы T были int или float .

Однако все, что нужно для того, чтобы T было чем-то вроде ] bignum значение класса, чтобы вызвать проблемы, которые действительно трудно диагностировать. Если вам повезет, они начнут проявляться на ранних этапах через нарушения прав доступа из-за разыменования указателей NULL, созданных memset () . Но Lady Luck - непостоянная любовница, и более вероятным результатом будет утечка памяти, и приложение становится «шатким». Или, более вероятно, «более шаткий».

ОП спросил в комментарии к другому ответу «...

16
ответ дан 8 December 2019 в 02:03
поделиться

Проблема в том, что это тип Pointer, который составляет 4 байта (в 32-битных системах), а int - 4 байта (на 32-битных системах). Попробуйте:

sizeof(*this)

Редактировать: Хотя я согласен с другими, что списки инициализаторов в конструкторе, вероятно, являются правильным решением здесь.

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

совершенно верно. Однако вместо того, чтобы конструировать x и y с 0, явный вызов конструктора по умолчанию установит для внутренних типов 0 и позволит использовать шаблон для структур и классов с конструктором по умолчанию.

template <class T>
class vector2
{
public:
    // use initializer lists
    vector2() : x(), y() {}
    T x;
    T y;
};
4
ответ дан 8 December 2019 в 02:03
поделиться

Не используйте memset. Это ужасно сломается на не POD-типах (и не обязательно будет легко отлаживаться), и в этом случае, вероятно, будет намного медленнее, чем простая инициализация обоих членов нулем (два назначения против вызова функции).

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

Если и когда вы хотите использовать функцию, подобную memset, по крайней мере, используйте std :: fill, который совместим с не POD-типами.

Если вы программируете на C ++, используйте инструменты, доступные в C ++. В противном случае назовите его C.

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

Не пытайтесь быть умнее компилятора. Используйте списки инициализаторов, как это предусмотрено языком. Компилятор знает, как эффективно инициализировать базовые типы.

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

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

Это может работать вместо:


char buffer[sizeof(vector2)];
memset(buffer, 0, sizeof(buffer));
vector2 *v2 = new (buffer) vector2();

.. или заменить / переопределить vector2 :: new, чтобы сделать что-то подобное. Тем не менее, мне все еще кажется странным.


vector2(): x(0), y(0), {}
1
ответ дан 8 December 2019 в 02:03
поделиться
Другие вопросы по тегам:

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