Я прочитал статью Скотта Майерса по этому вопросу и довольно смущен о том, о чем он говорит. У меня есть 3 вопроса.
Вопрос 1
Чтобы объяснить подробно, предположим, что я пишу простой класс vector<T>
с такими методами, как push_back
, insert
и operator []
. Если я последую за алгоритмом майнеров, я получаю все функции друзей, не являющихся членами. У меня будет векторный класс с несколькими частными членами и многими функциями друзей, не являющимися членами. Это то, о чем он говорит?
Вопрос 2
Я все еще не понимаю, как функции, отличные от членов, улучшают инкапсуляцию. Рассмотрим код, указанный в статье meyers.
class Point {
public:
int getXValue() const;
int getYValue() const;
void setXValue(int newXValue);
void setYValue(int newYValue);
private:
... // whatever...
};
Если его алгоритм соблюден, методы setXXXX
должны быть нечленными. Мой вопрос в том, как это увеличивает инкапсуляцию? Он также говорит
Теперь мы видели, что разумный способ для оценки количества инкапсуляции в классе - подсчитать количество функции, которые могут быть изменений в классе.
До тех пор, пока мы не сохраним сигнатуру метода без изменений, когда не будет изменена реализация класса, клиентский код не сломается, и он хорошо инкапсулирован, не так ли? То же самое относится и к функциям, не являющимся членами. Итак, в чем преимущество функции, отличной от члена?
Вопрос 3
Цитируя свой алгоритм
else if (f needs type conversions
on its left-most argument)
{
make f a non-member function;
if (f needs access to non-public
members of C)
make f a friend of C;
}
То, что он подразумевал под f, требует преобразования типов по его самому левому аргументу? Он также говорит следующее в статье.
Далее, теперь мы видим, что общее утверждение о том, что "функции друга нарушить инкапсуляцию" не совсем правда. Друзья не нарушают инкапсуляции, они просто уменьшают его - точно так же, как член функции.
Это и приведенный выше алгоритм противоречивы, верно?