Повторное использование кода: методы друзей с методами, не являющимися друзьями - PullRequest
1 голос
/ 28 октября 2011

Мне было интересно, можно ли повторно использовать код для methods с соответствующей версией friend? Например, в приведенном ниже примере оба метода doSomething и initDoSomething выполняют одни и те же вычисления, и поэтому их реализация практически одинакова. Что было бы лучшим способом сделать такую ​​вещь, чтобы повторно использовать код?

template < typename T >
class CFoo;

template < typename T > CFoo<T> doSomething( double );

template < typename T >
class CFoo{
    public:
        ...
        friend CFoo<T> doSomething< >( double );
        CFoo<T> initDoSomething( double );
};

Любые предложения приветствуются; -)

То, что я хотел бы достичь, это что-то вроде: myFooObject1 = doSomething(3.0); без необходимости обязательно инициализировать объект или также: myFooObject1.doSomething(3.0);

Ответы [ 2 ]

1 голос
/ 28 октября 2011

Вообще говоря, если функции требуется доступ к закрытым данным-членам класса, вы должны сделать это методом класса, а не другом-функцией. Существуют конкретные случаи, когда вы можете захотеть использовать функцию друга, например, с загруженной версией operator>> и т. Д., Чтобы создать общий интерфейс между вашими объектами и другими стандартными интерфейсами C ++, такими как потоки. Другим распространенным использованием автономной функции-друга может быть создание единого интерфейса функции, который будет каким-либо образом параметризован, но вы хотите сохранить интерфейс для этой функции одинаковым (т. Е. Одна шаблонная функция может принимать несколько разных типы классов, но вы хотите вызывать эту функцию одинаково с любой созданной экземпляром). Тем не менее, в общем, создание функций как друзей класса только для того, чтобы они могли получить доступ к закрытым данным, членам класса, в первую очередь нарушает идею инкапсуляции данных, которую классы создают для своих закрытых членов данных.

В вашем случае вы явно не объяснили, почему doSomething должен быть другом, а не методом ... как сейчас, с объявлением функции, кажется, нет никаких причин, почему это не может быть публичный метод CFoo. Во-вторых, если вы пытаетесь инициализировать глобальное состояние для вашей функции doSomething, вы захотите сделать initDoSomething статической функцией класса, а не метода, чтобы каждая версия CFoo<T> инициализировалась для вызов doSomething, а не только один экземпляр CFoo<T>. Как сейчас, вам придется инициализировать каждый экземпляр CFoo<T>, прежде чем его можно будет использовать с doSomething. Семантически это не имеет смысла, так как doSomething создает экземпляр CFoo<T>, прежде чем вы можете вызвать initDoSomething для этого экземпляра, чтобы инициализировать его для вызова doSomething.

0 голосов
/ 28 октября 2011

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

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

...