Дизайн класса с вектором в качестве частного / публичного члена? - PullRequest
2 голосов
/ 13 октября 2008

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

Требования:

1.Вектор внутри моего класса

2.Добавить и подсчет вектора необходим интерфейс

Ответы [ 6 ]

1 голос
/ 13 октября 2008

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

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

1 голос
/ 13 октября 2008

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

Жизнеспособной альтернативой представлению члена 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, что и вы, поэтому расположение этих переменных-членов может отличаться!

1 голос
/ 13 октября 2008

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

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

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

0 голосов
/ 13 октября 2008

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

0 голосов
/ 13 октября 2008

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

0 голосов
/ 13 октября 2008

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

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

Если это новое для нового, у вас есть чтение: http://en.wikipedia.org/wiki/Encapsulation_(classes_-_computers)

...