Каков наилучший способ доступа к внутренней структуре данных внутри класса?

#c #class #data-structures #sharing

#c #класс #структуры данных #совместное использование

Вопрос:

У меня есть класс A, состоящий из множества внутренних структур данных (например, m_data) и нескольких объектов (например, ClassB):

 class A
{
public:
      ...
private:
      int m_data[255];
      ClassB B[5];
}
  

Какой наилучший способ для B получить доступ к m_data? Я не хочу передавать m_data в функцию B..

// обновлено: Большое спасибо за ответы. Позвольте мне предоставить больше контекстной информации. Я работаю над проектом искусственного интеллекта, где я получаю некоторые данные (например, m_data [i]) на каждом временном шаге. Класс A должен буферизировать эту информацию (m_data) и использует список B (пример обновлен) для вывода. Сам класс B на самом деле является базовым классом, где разные дочерние элементы являются производными от него для разных целей, поэтому я предполагаю, что в этом контексте превращение B в подкласс A может быть не чистым (?)..

Комментарии:

1. Будет ли экземпляр B когда-либо существовать вне экземпляра класса A?

2. @mkb: если этого не произойдет, это должен быть вложенный класс.

3. В этом вопросе недостаточно информации, чтобы мы могли ответить на него с помощью разумного подхода C . Можете ли вы подробнее рассказать о взаимосвязи между A и B , их использовании и методах, к B которым требуется доступ m_data ?

Ответ №1:

 friend class ClassB;
  

Поместите эту строку в любом месте объявления A, если вы хотите, чтобы ClassB получал доступ ко всем защищенным и закрытым элементам A .

Комментарии:

1. Имейте в виду, что это кодирующий эквивалент высказывания: «Я хотел бы попасть на свою кухню из своей гостиной, поэтому я возьму кувалду и выбью стену, которая мешает». Это будет работать, это, безусловно, правильное решение, но, возможно, door будет более чистым вариантом.

Ответ №2:

Один из:

  • Сделайте ClassB другом
  • Сделайте A подклассом ClassB и сделайте m_data protected вместо private

[В ответ на комментарий Марка Б.]

Если когда-нибудь вы почувствуете необходимость прибегнуть к friend связи, дизайн следует пересмотреть — это может оказаться неуместным. Подклассы могут иметь или не иметь смысла; вы должны спросить себя: «Есть class A и вроде class ClassB ?» Если вопрос интуитивно не имеет смысла или ответ просто отрицательный, то это может быть неподходящим решением.

Комментарии:

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

Ответ №3:

В идеале вы вообще не разрешаете внешний доступ к структуре данных. Вам следует пересмотреть свой подход, уделяя больше внимания вопросу «Каковы функциональные требования / варианты использования, необходимые для ClassB для доступа к экземплярам A», а не перекладывать управление внутренними элементами на методы, не управляемые внутри class A . Вы обнаружите, что ограничение управления внутренними элементами классом, владеющим этими элементами, приведет к более чистому коду, который легче отлаживается.

Однако, если по какой-то причине это непрактично для вашей ситуации, есть пара возможностей, которые приходят на ум:

  • Вы можете предоставить простые методы доступа get / set, которые, в зависимости от ваших требований, могут использоваться для доступа либо к копии, либо к ссылке на m_data. Недостатком этого является то, что он позволяет всем получать доступ, но делает это только через четко определенные интерфейсы (которые можно отслеживать по мере необходимости).
  • ggPeti упоминает использование friend , которое может сработать для вас, но оно дает ClassB доступ ко всем внутренним элементам A.

Ответ №4:

Функция getData(), которая возвращает m_data . Используйте setData() для изменения значения.

Итак, в функции класса B вы должны создать указатель на переменную класса типа A, которую вы создали. Давайте просто назовем этот указатель ‘p’.

Просто сделайте p-> getData() , p.getData() может быть ответом. Я думаю, что они делают то же самое, но c использует ‘->’, а некоторые другие языки используют ‘.’. Хотя не цитируйте меня по этому поводу.

Удачи, сэр. Надеюсь, я тебе помог.

Ответ №5:

Какой наилучший способ для B получить доступ к m_data?

Зависит от использования.

Вот как бы я это сделал :

 class ClassB
{
  // ...
  void foo( A amp;a )
  {
    // use a's data
  }
};
class A
{
  //...
  int m_data[255];
  ClassB amp; B;
};
  

В зависимости от реализации, возможно, ClassB вообще не нужен. Возможно, его методы можно преобразовать в функции.