Дизайн класса с вектором в качестве частного/публичного члена?

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

  •  10-07-2019
  •  | 
  •  

Вопрос

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

Требования:

1.Vector<someclass> внутри моего класса

2. Требуется интерфейс добавления и подсчета векторов.

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

Решение

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

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

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

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

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

Например, для члена Vector вы можете написать методы AddItem и Clear, если это все функциональные возможности, которые вы хотите предоставить.

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

Реальная альтернатива разоблачению vector член создает функцию посетителя (или внутренний итератор).Таким образом вы лучше подчиняетесь закону Деметры:

class ContWrapper {
    std::vector<int> _ints;
public:
    class Action {
    public: 
        virtual void accept( int i ) = 0;
    };
    void each_int( Action& a );
};

Также будьте очень осторожны при экспорте, например.а std::vector<T> тоже из библиотеки:клиентский код может не использовать ту же реализацию STL, что и вы, поэтому расположение этих переменных-членов может отличаться!

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

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

Если это что-то новое, вы можете прочитать: http://en.wikipedia.org/wiki/Encapsulation_(classes__-_computers)

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

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

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