C ++ должен все переменные-члены использовать методы доступа и мутатор - PullRequest
0 голосов
/ 10 марта 2011

У меня около 15 ~ 20 переменных-членов, к которым нужно получить доступ, мне было интересно, было бы хорошо, если бы они были публичными, вместо того, чтобы давать каждой из них функции get / set.

код был бы что-то вроде

class A { // a singleton class
public:
    static A* get();

    B x, y, z;
    // ... a lot of other object that should only have one copy
    // and doesn't change often

private:
    A();
    virtual ~A();
    static A* a;
};

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

РЕДАКТИРОВАТЬ:

Есть ли лучший способ, чем класс Singleton, чтобы поместить их в коллекцию

Ответы [ 6 ]

4 голосов
/ 10 марта 2011

Мир C ++ не настолько одержим идеей "все должно быть спрятано за аксессорами / мутаторами / что бы они ни решали называть их сегодня", как некоторые языки с поддержкой ОО.

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

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

Если класс на самом деле что-то делает, однако, вы можете найти более подходящим сгруппировать ваши процедуры get / set вместе по функции /аспект или интерфейс.

Как я уже говорил, трудно сказать без дополнительной информации.

РЕДАКТИРОВАТЬ: Singleton-классы не являются вонючим кодом сами по себе, но вы должны бытьнемного осторожнее с ними.Если синглтон заботится о данных предпочтения или о чем-то подобном, имеет смысл создавать отдельные средства доступа для каждого элемента данных.

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

2 голосов
/ 10 марта 2011

Это действительно зависит от того, почему вы хотите предоставить им доступ, какова вероятность того, что они изменятся, сколько кода использует их, насколько проблематично иметь необходимость переписывать или перекомпилировать этот код, насколько быстрым должен быть доступ, нужны ли вам/ хочу virtual доступ, что более удобно и интуитивно понятно при использовании кода и т. д. Желание предоставить доступ ко многим вещам может свидетельствовать о плохом дизайне или 100% -ном подходе.Использование функций get / set имеет гораздо больше потенциальных преимуществ для нестабильного (нестабильного / возможно подверженного частым изменениям) низкоуровневого кода, который может использоваться большим количеством клиентских приложений.

Учитывая ваши изменения, массив создаетсмысл, если ваш клиент, вероятно, захочет получить доступ к значениям в цикле, или числовой индекс по своей сути имеет смысл.Например, если это хронологически упорядоченные выборки данных, индекс звучит хорошо.В целом, массивы облегчают предоставление алгоритмов для работы с любыми или всеми индексами - вы должны решить, полезно ли это для ваших клиентов;в противном случае попытайтесь избежать этого, поскольку это может упростить ошибочный доступ к неправильным значениям, особенно если, скажем, два человека разветвляют некоторый код, добавляют дополнительное значение в конце, а затем пытаются объединить их изменения.Иногда имеет смысл предоставить массивы и именованный доступ или перечисление со значимыми именами для индексов.

2 голосов
/ 10 марта 2011

Нет, это не будет хорошо. Изображение, которое вы хотите изменить в будущем. Например, удалите одну переменную-член и позвольте функциям get / set вычислить ее значение.

2 голосов
/ 10 марта 2011

Вы можете поместить их в структуру POD и предоставить доступ к объекту этого типа:

struct VariablesHolder
{
  int a;
  float b;
  char c[20];
};


class A
{
  public: 
    A() : vh()
    {
    }

    VariablesHolder& Access()
    {
      return vh;
    }
    const VariablesHolder& Get() const
    {
      return vh;
    }

  private:
    VariablesHolder vh;
};
1 голос
/ 11 марта 2011

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

  1. Не использовать синглетоны или глобальные переменные; они вводят тонкие, неявные зависимости между компонентами, которые позволяют, казалось бы, независимым компонентам мешать друг другу.
  2. Делайте переменные const везде, где это возможно, и устанавливайте параметры только там, где это абсолютно необходимо.
  3. Никогда не делайте переменные общедоступными (если вы не создаете структуру POD, и даже тогда лучше создавать структуры POD только в качестве внутренней детали реализации, а не представлять их в API).

Также вы упомянули, что вам нужно использовать массив. Вы можете использовать vector<B> или vector<B*> для создания массива объектов динамического размера типа B или типа B *. Вместо использования A::getA() для доступа к вашему экземпляру синглтона; было бы лучше иметь функции, которым требуется тип A, чтобы получить параметр типа const A&. Это сделает зависимость явной, а также ограничит, какие функции могут изменять члены этого класса (передайте A* или A& функциям, которые должны изменить его).

0 голосов
/ 10 марта 2011

По соглашению, если вы хотите, чтобы структура данных содержала несколько открытых полей (простые старые данные), я бы предложил использовать структуру (и использовать в тандеме с другими классами - builder, flyweight, memento и другими шаблонами проектирования).).

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

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

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

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

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