Сведения о вопросе

Life

16:03, 1st July, 2020

Теги

c++   oop   class   nested-class    

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

Просмотров: 448   Ответов: 10

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

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

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



  Сведения об ответе

crush

18:03, 1st July, 2020

Я бы немного неохотно использовал здесь вложенные классы. Что, если вы создадите абстрактный базовый класс для "multimedia driver" для обработки внутренних материалов (рабочая лошадка) и отдельный класс для фронтальной работы? Внешний класс может взять указатель / ссылку на реализованный класс драйвера (для соответствующего типа media и ситуации) и выполнить абстрактные операции над структурой рабочей лошадки.

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

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


  Сведения об ответе

PIRLO

18:03, 1st July, 2020

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

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

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


  Сведения об ответе

SKY

18:03, 1st July, 2020

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

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


  Сведения об ответе

SSESION

18:03, 1st July, 2020

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


  Сведения об ответе

pumpa

18:03, 1st July, 2020

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


  Сведения об ответе

9090

18:03, 1st July, 2020

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

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

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


  Сведения об ответе

lesha

18:03, 1st July, 2020

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


  Сведения об ответе

ITSME

18:03, 1st July, 2020

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

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


  Сведения об ответе

PAGE

18:03, 1st July, 2020

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


  Сведения об ответе

FAriza

18:03, 1st July, 2020

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться