Разработка программы относительно полиморфизма и Управление ресурсами

У меня есть класс под названием Widget, Этот класс является абстрактным и имеет виртуальные методы. Чтобы избежать нарезки всего объекта Widgets хранятся в виде ссылок или указателей. У меня есть несколько классов с конструкторами, которые хранят внутренний виджет, данный им; Таким образом Widget сохраненный должен быть инициализирован за пределами конструктора и не может быть уничтожен до объекта, поэтому обычно Widget выделяется через динамическую память. Мой вопрос касается того, как обращаться с этой динамической памятью; Я составил список вариантов (не стесняйтесь предлагать другие). Какой из них наиболее идиоматичен?

1. Умные указатели. Умные указатели кажутся правильным выбором, но, поскольку я использую C ++ 98, я должен написать свой собственный. Я также думаю, что написание smart_pointer<Widget> все время немного некрасиво.

2. Копировать Widgets когда хранится. Другой способ действий — сохранить копию переданного Widget вместо оригинала. Это может вызвать нарезку объектов, но я не уверен. Кроме того, пользователи могут захотеть написать классы, которые хранят переданные Widgetsи я не хотел бы сделать это слишком сложным.

3. Позвольте пользователю обрабатывать все. Я мог бы заставить пользователя убедиться, что Widget удаляется вовремя. Похоже, это то, что делает Qt (?). Однако, это снова усложняет ситуацию для пользователя.

1

Решение

Мне лично нравится такой подход (он не всегда применим, но я успешно использовал его несколько раз):

class WidgetOwner
{
vector<Widget*> m_data;
public:
RegisterWidget(Widget *p) { m_data.push_back(p); }
~WidgetOwner() { for (auto &p : m_data) delete p; }
};

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

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

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

1

Другие решения

Какой самый идиоматичный?

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

Вы также можете решить, что, поскольку вы используете c++98 (это огромный фактор, который нужно принимать во внимание), вы берете то, что идиоматично для этого контекста, и, поскольку это было практически ничем не предназначено для человека, ответ, скорее всего, заключается в том, какой домашний дизайн вам наиболее нравится.

1

Я думаю, что умный указатель — лучший выбор. И если вы чувствуете, что шаблон некрасив, попробуйте typedef

0
По вопросам рекламы [email protected]