Должен ли я использовать вложенные классы в этом случае?

StackOverflow https://stackoverflow.com/questions/330

  •  08-06-2019
  •  | 
  •  

Вопрос

Я работаю над коллекцией классов, используемых для воспроизведения и записи видео.У меня есть один основной класс, который действует как общедоступный интерфейс с такими методами, как play(), stop(), pause(), record() и т. д...Затем у меня есть рабочие классы, которые выполняют декодирование и кодирование видео.

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

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

Это было полезно?

Решение

Мне бы не хотелось использовать здесь вложенные классы.Что, если вы создадите абстрактный базовый класс для «мультимедийного драйвера» для обработки внутренней части (рабочей лошадки) и отдельный класс для внешней работы?Интерфейсный класс может принимать указатель/ссылку на реализованный класс драйвера (для соответствующего типа носителя и ситуации) и выполнять абстрактные операции над структурой рабочей лошадки.

Моя философия заключалась бы в том, чтобы сделать обе структуры доступными для клиента в отточенном виде, при условии, что они будут использоваться в тандеме.

Я бы сослался на что-то вроде QTextDocument в Кт.Вы предоставляете прямой интерфейс для обработки данных на «голом железе», но передаете полномочия объекту, такому как QTextEdit, для выполнения манипуляций.

Другие советы

Вы можете использовать вложенный класс для создания (небольшого) вспомогательного класса, необходимого для реализации основного класса.Или например определить интерфейс (класс с абстрактными методами).

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

Вместо этого поместите другие классы в отдельные файлы .h/.cpp, которые затем можно будет использовать в классе VideoPlayer.Клиенту VideoPlayer теперь нужно только включить файл, объявляющий VideoPlayer, и ему по-прежнему не нужно знать, как вы его реализовали.

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

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

звучит как случай, когда вы могли бы использовать шаблон стратегии

Иногда уместно скрыть классы реализации от пользователя — в таких случаях лучше поместить их в файл foo_internal.h, чем внутри определения общедоступного класса.Таким образом, читатели вашего foo.h не увидят того, о чем вы предпочитаете, чтобы их не беспокоили, но вы все равно можете писать тесты для каждой конкретной реализации вашего интерфейса.

Мы столкнулись с проблемой полустарого компилятора Sun C++ и видимости вложенных классов, поведение которых изменилось в стандарте.Конечно, это не повод не использовать вложенный класс, просто об этом следует знать, если вы планируете компилировать свое программное обеспечение на множестве платформ, включая старые компиляторы.

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

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

Вот дополнительная информация о Шаблон PIMPL (раздел 3.1.1).

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

Ваш класс кодера/декодера звучит так, как будто он лучше соответствует Стратегический шаблон

Одна из причин избегать вложенных классов — если вы когда-нибудь захотите обернуть код с помощью swig (http://www.swig.org) для использования с другими языками.В настоящее время у Swig есть проблемы с вложенными классами, поэтому взаимодействие с библиотеками, предоставляющими любые вложенные классы, становится настоящей проблемой.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top