Я могу реализовать Шаблон "фабричный метод" в C++, не используя новый?

ServletContext отличается от «вложения» ApplicationContext. Документ Java говорит следующее для ServletContext

Существует один контекст [сервлет] для «веб-приложения» на виртуальную машину Java. («Веб-приложение» - это набор сервлетов и контента, установленных в определенном подмножестве пространства имен URL-адреса сервера, например / catalog, и, возможно, установленном через файл .war.)

Поскольку более одного «веб-приложения» под одним и тем же AppBase, каждое из которых имеет свои собственные DocBase, WEB-INF/web.xml и т. д., определенно существует общая среда / контекст, который является общим для всех «веб-приложений», о котором идет речь как ApplicationContext. В случае JSF PortletContext является противоположностью ServletContext, а ApplicationContext называется ExternalContext.

7
задан Matthew Murdoch 1 September 2009 в 10:09
поделиться

7 ответов

Поскольку компилятор AVR основан на компиляторе gcc, он, скорее всего, будет поддерживать ключевое слово new. Какую именно ошибку вы получаете. Я предполагаю, что это ошибка ссылки / компилятора, связанная с неопределенной функцией, а именно с оператором new. Существует разница между оператором new и оператором new: первый используется для создания объектов, а второй - для выделения памяти для объектов. Оператор new вызывает оператор new для типа создаваемого объекта, затем инициализирует v-таблицу объекта и вызывает конструкторы объекта. В этом FAQ говорится, что оператор new не определен в стандартных библиотеках. Это легко исправить, просто определите один:

void *operator new (size_t size)
{
  return some allocated memory big enough to hold size bytes
}

, и вам также нужно будет определить удаление:

void operator delete (void *memory)
{
   free the memory
}

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

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

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

8
ответ дан 6 December 2019 в 14:07
поделиться

А что насчет этого?

MyClass *objp = (MyClass*)malloc(sizeof(MyClass));
*objp = MyClass();  // or any other c'tor

РЕДАКТИРОВАТЬ: Забыл упомянуть, предполагается, что в MyClass есть оператор присваивания.

РЕДАКТИРОВАТЬ2: Еще кое-что, что я забыл - да, есть ошибка (это C ++, всегда есть подводные камни). Вам придется вручную вызывать d'tor для объекта, так как вы не можете использовать бесплатно.

1
ответ дан 6 December 2019 в 14:07
поделиться

Вы умеете делать malloc? Если это так, вы можете таким образом выделить свой объект.

Также какова природа ваших объектов, которые вы хотите создать из Factory?

  • Имитируемы ли они?
  • Предполагается ли, что фабрика производит только ограниченный набор объектов, которые могут быть известны во время компиляции?

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

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

0
ответ дан 6 December 2019 в 14:07
поделиться

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

3
ответ дан 6 December 2019 в 14:07
поделиться

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

0
ответ дан 6 December 2019 в 14:07
поделиться

Общая картина фабричного метода - это создание объекта, что означает потребление памяти кучи. Во встроенной системе вы ограничены оперативной памятью и должны принимать все свои проектные решения с учетом ограничений памяти. ATmega328 имеет всего 2 КБ ОЗУ. Я бы не рекомендовал использовать динамически выделяемую память в таком ограниченном пространстве.

Не зная более подробно о вашей проблеме, я бы рекомендовал статически объявить несколько экземпляров класса и повторно использовать эти экземпляры каким-либо образом. Это означает, что вам нужно знать, когда и почему ваши объекты создаются и - КАК ВАЖНО - когда и почему они заканчиваются; тогда вам нужно выяснить, сколько вам нужно быть активными одновременно и сколько можно активировать одновременно.

!! Дин

3
ответ дан 6 December 2019 в 14:07
поделиться

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

// Class File ---------------------------------------------------
class MyObject {
    public:
        MyObject* getObject();

    private:
        const int MAX_POSSIBLE_COUNT_OF_OBJECTS = 10;
        static MyObject allocatedObjects[MAX_POSSIBLE_COUNT_OF_OBJECTS];

        static allocatedObjectIndex = 0;
};

// Implementation File ------------------------------------------

// Instantiate a static array of your objects.
static MyObject::allocatedObject[MAX_POSSIBLE_COUNT_OF_OBJECTS];

// Your method to return already created objects.
MyObject* MyObject::getObject() {

    if (allocatedObjectIndex < (MAX_POSSIBLE_COUNT_OF_OBJECTS - 1)) {
        return allocatedObjects[allocatedObjectIndex++];
    } else {
        // Log error if possible
        return NULL;
    }
}

Будьте предупреждены. Это все из памяти, поскольку я не писал ни одного C ++ более 8 месяцев.

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

0
ответ дан 6 December 2019 в 14:07
поделиться
Другие вопросы по тегам:

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