Какие виды использования используются для «размещения новых»?

Если вы счастливы иметь зависимость от сборки System.Web.Helpers, то вы можете использовать класс Json :

dynamic data = Json.Decode(json);

Он включен в MVC в качестве дополнительной загрузки в среду .NET 4. Обязательно дайте Владу вздохнуть, если это будет полезно! Однако, если вы не можете предположить, что клиентская среда включает эту DLL, тогда прочитайте.


Альтернативный подход к десериализации предлагается здесь здесь . Я немного модифицировал код, чтобы исправить ошибку и подобрать стиль моего кодирования. Все, что вам нужно, это этот код и ссылка на System.Web.Extensions из вашего проекта:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Web.Script.Serialization;

public sealed class DynamicJsonConverter : JavaScriptConverter
{
    public override object Deserialize(IDictionary dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");

        return type == typeof(object) ? new DynamicJsonObject(dictionary) : null;
    }

    public override IDictionary Serialize(object obj, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override IEnumerable SupportedTypes
    {
        get { return new ReadOnlyCollection(new List(new[] { typeof(object) })); }
    }

    #region Nested type: DynamicJsonObject

    private sealed class DynamicJsonObject : DynamicObject
    {
        private readonly IDictionary _dictionary;

        public DynamicJsonObject(IDictionary dictionary)
        {
            if (dictionary == null)
                throw new ArgumentNullException("dictionary");
            _dictionary = dictionary;
        }

        public override string ToString()
        {
            var sb = new StringBuilder("{");
            ToString(sb);
            return sb.ToString();
        }

        private void ToString(StringBuilder sb)
        {
            var firstInDictionary = true;
            foreach (var pair in _dictionary)
            {
                if (!firstInDictionary)
                    sb.Append(",");
                firstInDictionary = false;
                var value = pair.Value;
                var name = pair.Key;
                if (value is string)
                {
                    sb.AppendFormat("{0}:\"{1}\"", name, value);
                }
                else if (value is IDictionary)
                {
                    new DynamicJsonObject((IDictionary)value).ToString(sb);
                }
                else if (value is ArrayList)
                {
                    sb.Append(name + ":[");
                    var firstInArray = true;
                    foreach (var arrayValue in (ArrayList)value)
                    {
                        if (!firstInArray)
                            sb.Append(",");
                        firstInArray = false;
                        if (arrayValue is IDictionary)
                            new DynamicJsonObject((IDictionary)arrayValue).ToString(sb);
                        else if (arrayValue is string)
                            sb.AppendFormat("\"{0}\"", arrayValue);
                        else
                            sb.AppendFormat("{0}", arrayValue);

                    }
                    sb.Append("]");
                }
                else
                {
                    sb.AppendFormat("{0}:{1}", name, value);
                }
            }
            sb.Append("}");
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (!_dictionary.TryGetValue(binder.Name, out result))
            {
                // return null to avoid exception.  caller can check for null this way...
                result = null;
                return true;
            }

            result = WrapResultObject(result);
            return true;
        }

        public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
        {
            if (indexes.Length == 1 && indexes[0] != null)
            {
                if (!_dictionary.TryGetValue(indexes[0].ToString(), out result))
                {
                    // return null to avoid exception.  caller can check for null this way...
                    result = null;
                    return true;
                }

                result = WrapResultObject(result);
                return true;
            }

            return base.TryGetIndex(binder, indexes, out result);
        }

        private static object WrapResultObject(object result)
        {
            var dictionary = result as IDictionary;
            if (dictionary != null)
                return new DynamicJsonObject(dictionary);

            var arrayList = result as ArrayList;
            if (arrayList != null && arrayList.Count > 0)
            {
                return arrayList[0] is IDictionary 
                    ? new List(arrayList.Cast>().Select(x => new DynamicJsonObject(x))) 
                    : new List(arrayList.Cast());
            }

            return result;
        }
    }

    #endregion
}

Вы можете использовать его следующим образом:

string json = ...;

var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new DynamicJsonConverter() });

dynamic obj = serializer.Deserialize(json, typeof(object));

Итак, учитывая строку JSON :

{
  "Items":[
    { "Name":"Apple", "Price":12.3 },
    { "Name":"Grape", "Price":3.21 }
  ],
  "Date":"21/11/2010"
}

Следующий код будет работать во время выполнения:

dynamic data = serializer.Deserialize(json, typeof(object));

data.Date; // "21/11/2010"
data.Items.Count; // 2
data.Items[0].Name; // "Apple"
data.Items[0].Price; // 12.3 (as a decimal)
data.Items[1].Name; // "Grape"
data.Items[1].Price; // 3.21 (as a decimal)

375
задан JP P. 26 March 2019 в 22:11
поделиться

14 ответов

Новое размещение позволяет Вам создавать объект в памяти, это уже выделяется.

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

DevX дает хороший пример :

Стандартный C++ также поддерживает размещение новый оператор, который создает объект на предварительно выделенном буфере. Это полезно при создании пула памяти, сборщика "мусора" или просто когда производительность и безопасность исключения являются главными (нет никакой опасности отказа выделения, так как память была уже выделена, и построение объекта на предварительно выделенном буфере занимает меньше времени):

char *buf  = new char[sizeof(string)]; // pre-allocated buffer
string *p = new (buf) string("hi");    // placement new
string *q = new string("hi");          // ordinary heap allocation

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

Освобождение в размещении, новом

, Вы не должны освобождать каждый объект, который использует буфер памяти. Вместо этого необходимо удалить [] только исходный буфер. Необходимо было бы тогда назвать деструкторы классов вручную. Для хорошего предложения на этом посмотрите FAQ Stroustrup на: там "размещение, удаляют" ?

338
ответ дан Alan 26 March 2019 в 22:11
поделиться

Механизмы выполнения сценария могут использовать его в собственном интерфейсе для выделения собственных объектов из сценариев. См. Angelscript (www.angelcode.com/angelscript) для примеров.

4
ответ дан Raindog 26 March 2019 в 22:11
поделиться
  • 1
    - noexit работается отлично. Поскольку я подозревал, it' s что-то я могу, вероятно, выяснить меня. В противном случае I' ll вернуться. – jadero 27 August 2009 в 19:51

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

6
ответ дан Steve Fallows 26 March 2019 в 22:11
поделиться

Это используется std::vector<>, потому что std::vector<> обычно выделяет больше памяти, чем существует objects в vector<>.

7
ответ дан Andreas Magnusson 26 March 2019 в 22:11
поделиться

Я видел, что это использовало в качестве небольшой взлом производительности для "динамического типа" указатель (в разделе "Under the Hood"):

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

7
ответ дан Max Lybbert 26 March 2019 в 22:11
поделиться

Одно место я натыкался на него, находится в контейнерах, которые выделяют непрерывный буфер и затем заполняют его объектами как требуется. Как упомянуто, станд.:: вектор мог бы сделать это, и я знаю некоторые версии MFC, CArray и/или CList сделали это (потому что это - то, где я сначала натыкался на него). Буферный сверхметод назначения является очень полезной оптимизацией, и новое размещение является в значительной степени единственным способом создать объекты в том сценарии. Это также используется иногда для построения объектов в блоках памяти, выделенных за пределами прямого кода.

я использовал его в подобной способности, хотя это часто не подходит. Это - полезный инструмент для панели инструментов C++, все же.

4
ответ дан Nick 26 March 2019 в 22:11
поделиться

Обычно новое размещение используется для избавлений от стоимости выделения 'нормальный новый'.

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

5
ответ дан xtofl 26 March 2019 в 22:11
поделиться

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

7
ответ дан Martin Beckett 26 March 2019 в 22:11
поделиться
  • 1
    В зависимости от браузера и версии parseInt (" 09") может возвратиться 0. Это - ошибка. – JonH 9 October 2009 в 18:34

Полезно при создании ядра - куда Вы помещаете, ядро кодируют Вас чтение от диска или pagetable? Необходимо знать, где перейти к.

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

я также полагаю, что некоторые реализации STL используют новое размещение, как станд.:: вектор. Они выделяют комнату для 2^n элементы тот путь и не нуждаются к всегда перевыделению.

8
ответ дан mstrobl 26 March 2019 в 22:11
поделиться
  • 1
    @MatthewCrumley— старый комментарий, но какого черта - ES5 удаляет то поведение, так совместимые браузеры , должен обработка parseInt('08') как основа 10. – RobG 14 September 2012 в 10:42

Я использовал его для построения объектов, выделенных на стеке через alloca ().

бесстыдный разъем: я вел блог об этом здесь .

23
ответ дан NathanOliver 26 March 2019 в 22:11
поделиться

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

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

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

32
ответ дан T.E.D. 26 March 2019 в 22:11
поделиться

Полезно, если Вы хотите разделить выделение от инициализации. STL использует размещение, новое для создания контейнерных элементов.

50
ответ дан Tim Cooper 26 March 2019 в 22:11
поделиться

Мы используем его с пользовательскими пулами памяти. Просто эскиз:

class Pool {
public:
    Pool() { /* implementation details irrelevant */ };
    virtual ~Pool() { /* ditto */ };

    virtual void *allocate(size_t);
    virtual void deallocate(void *);

    static Pool::misc_pool() { return misc_pool_p; /* global MiscPool for general use */ }
};

class ClusterPool : public Pool { /* ... */ };
class FastPool : public Pool { /* ... */ };
class MapPool : public Pool { /* ... */ };
class MiscPool : public Pool { /* ... */ };

// elsewhere...

void *pnew_new(size_t size)
{
   return Pool::misc_pool()->allocate(size);
}

void *pnew_new(size_t size, Pool *pool_p)
{
   if (!pool_p) {
      return Pool::misc_pool()->allocate(size);
   }
   else {
      return pool_p->allocate(size);
   }
}

void pnew_delete(void *p)
{
   Pool *hp = Pool::find_pool(p);
   // note: if p == 0, then Pool::find_pool(p) will return 0.
   if (hp) {
      hp->deallocate(p);
   }
}

// elsewhere...

class Obj {
public:
   // misc ctors, dtors, etc.

   // just a sampling of new/del operators
   void *operator new(size_t s)             { return pnew_new(s); }
   void *operator new(size_t s, Pool *hp)   { return pnew_new(s, hp); }
   void operator delete(void *dp)           { pnew_delete(dp); }
   void operator delete(void *dp, Pool*)    { pnew_delete(dp); }

   void *operator new[](size_t s)           { return pnew_new(s); }
   void *operator new[](size_t s, Pool* hp) { return pnew_new(s, hp); }
   void operator delete[](void *dp)         { pnew_delete(dp); }
   void operator delete[](void *dp, Pool*)  { pnew_delete(dp); }
};

// elsewhere...

ClusterPool *cp = new ClusterPool(arg1, arg2, ...);

Obj *new_obj = new (cp) Obj(arg_a, arg_b, ...);

Теперь можно кластеризировать объекты вместе на единственной арене памяти, выбрать средство выделения, которое очень быстро, но не делает никакого освобождения, использует размещение в ОЗУ и любого другого семантического, Вы хотите наложить путем выбора пула и передачи его как аргумента размещению объекта новый оператор.

57
ответ дан Don Wakefield 26 March 2019 в 22:11
поделиться
  • 1
    Сбои, если файл содержит ' ~ ' символ – William Pursell 27 July 2009 в 10:05

Компьютерщик: БИНГО! Вы получили это полностью - это именно то, для чего он идеально подходит. Во многих встроенных средах внешние ограничения и / или общий сценарий использования вынуждают программиста отделить выделение объекта от его инициализации. В совокупности C ++ называет это «созданием экземпляра»; но всякий раз, когда действие конструктора должно быть вызвано явно БЕЗ динамического или автоматического выделения, размещение new - это способ сделать это. Это также идеальный способ найти глобальный объект C ++, который привязан к адресу аппаратного компонента (ввод-вывод с отображением памяти) или для любого статического объекта, который по какой-либо причине должен находиться по фиксированному адресу.

13
ответ дан 22 November 2019 в 23:51
поделиться
Другие вопросы по тегам:

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