Классы и переменные-члены - PullRequest
0 голосов
/ 07 января 2011

Допустим, у меня есть контейнерный класс с именем myList. Этот контейнерный класс имеет закрытую переменную-член с именем capacity, которая содержит количество значений в экземпляре.

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

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

myList myInstance;
myInstance.capacity = 123;

Будет ли считаться плохой практикой иметь открытую функцию-член, которая просто возвращает значение capacity, которая будет закрытой переменной? Например:

unsigned int getCapacity()
{
    return capacity;
}

А как насчет переменной "клон", которая обновляется до значения capacity всякий раз, когда изменяется значение capacity? Пользователи класса будут иметь доступ к общедоступному «клону», а не к самой закрытой переменной.

Ответы [ 7 ]

4 голосов
/ 07 января 2011

Иметь средство получения емкости.
Но пометить его как постоянный член:

unsigned int getCapacity()  const
{                        //^^^^^^^ 
    return capacity;
}

Второе решение не работает.
Поскольку оно ненадежно (один пользователь может обновить его тогдаследующий пользователь получит недопустимое значение, когда прочитает его).

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

Таким образом, вы хотите предварительно выделить память, если емкости недостаточно?

MyList   x;
// I am going to add 10 items make sure there is enough room.
if (x.size() + 10 < x.capacity())
{    x.resize(x.size() + 10);
}

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

x.resize(x.size() + 10);  // If the container has enough space do nothing. 
                          // Otherwise make sure there is enough room for 10 more items.

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

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

2 голосов
/ 07 января 2011

Первое решение, которое вы описываете, называется геттером, и рекомендуется иметь их.

Второе решение на самом деле не является решением, оно просто добавляет вторую переменную и вводит необходимостьобновите его.

2 голосов
/ 07 января 2011

Аксессор является хорошим решением.Это тот, который выбрал STL.Смотрите std :: vector ::acity (), std :: vector :: size (), ...

1 голос
/ 07 января 2011

совсем не плохая практика, вот как это нужно делать на самом деле.

1 голос
/ 07 января 2011

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

0 голосов
/ 07 января 2011

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

0 голосов
/ 07 января 2011

Если у вас есть публичный получатель, вы можете просто вернуть копию или постоянную ссылку на емкость.

Это позволит клиенту видеть, но не изменять данные.

...