Язык C++ поддерживает функцию инкапсуляции, при которой данные объединяются с функциями. После объединения, данные доступны только функциям, работающим с ними.
Это одна из отличительных особенностей C++, которая сохраняет данные и предотвращает их утечку вне программы.
Но в некоторых приложениях нам иногда может понадобиться доступ к данным за пределами связанного устройства. Например, сторонний класс может захотеть получить доступ к закрытым и защищенным данным класса C++.
C++ предоставляет средство для доступа к частным и защищенным данным с помощью специальной функции, называемой дружественной функцией или классом, которую мы обсудим в данной статье.
Дружественная функция в C++ — это функция, которой предшествует ключевое слово «friend» (друг). Когда функция объявлена как друг, она может получить доступ к закрытым и защищенным членам данных класса.
Дружественная функция объявляется внутри класса с предшествующим ключевым словом friend, как показано ниже:
class className{ …… friend returnType functionName(arg list); }; |
Как показано выше, дружественная функция объявлена внутри класса, к закрытым и защищенным членам которого необходимо получить доступ. Функция может быть определена в любом месте файла кода, и нам не нужно использовать ключевое слово «friend» или оператор разрешения области видимости.
Есть несколько моментов, которые следует помнить при реализации дружественных функций в программе:
- Дружественная функция может быть объявлена в частной или общедоступной части класса.
- Дружественную функцию можно вызывать как обычную функцию без использования объекта.
- Дружественная функция не входит в область действия класса, другом которого она является.
- Дружественная функция не вызывается с использованием объекта класса, поскольку она не входит в область действия класса.
- Дружественная функция не может напрямую обращаться к закрытым и защищенным членам данных класса.
- Дружественная функция должна использовать объект класса, а затем обращаться к членам с помощью оператора точки.
- Дружественная функция может быть глобальной функцией или членом другого класса.
Пример дружественной функции
Давайте разберем пример программирования, чтобы лучше понять использование дружественной функции:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream> #include <string> using namespace std; class sample{ int length, breadth; public: sample(int length, int breadth):length(length),breadth(breadth) {} friend void calcArea(sample s); //объявление дружественной функции }; //определение дружественной функции void calcArea(sample s){ cout<<"Area = "<<s.length * s.breadth; } int main() { sample s(10,15); calcArea(s); return 0; } |
Вывод данных:
Area = 150 |
В приведенной выше программе есть пример класса с закрытыми членами длины и ширины. Также есть public constructor, который инициализирует значения длины и ширины. Далее у нас есть дружественная функция «calcArea», которая вычисляет площадь, принимая во внимание длину и ширину.
Обратите внимание, что calcArea является дружественной функцией и не является частью класса. В основной функции, после создания объекта образца класса, мы передаем его в функцию calcArea, которая вычисляет площадь и отображает значение.
Дружественный класс
Если есть дружественная функция, значит может быть и дружественный класс. Дружественный класс может получить доступ к закрытым и защищенным членам класса, для которого он является другом.
class A{ …… friend class B; }; class B{ …….. }; |
Как показано выше, класс B является дружественным по отношению к классу A. Таким образом, класс B может получить доступ к закрытым и защищенным членам класса A.
Но это не означает, что класс A может получить доступ к закрытым и защищенным членам класса B. Также, дружественность класса не передается по наследству. Это означает, что поскольку класс B является другом класса A, он не будет другом подклассов класса A.
Давайте разберем пример программирования, в котором демонстрируется работа дружественного класса:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#include <iostream> #include <string> using namespace std; class Area{ int length,breadth,area; public: Area(int length,int breadth):length(length),breadth(breadth) {} void calcArea(){ area = length * breadth; } friend class printClass; }; class printClass{ public: void printArea(Area a){ cout<<"Area = "<<a.area; } }; int main(){ Area a(10,15); a.calcArea(); printClass p; p.printArea(a); return 0; } |
Вывод данных:
Area = 150 |
В этой программе есть два класса. Класс «“Area» (площадь), который вычисляет площадь, используя параметры длины и ширины. Обратите внимание, что поля, площадь, длина и ширина являются закрытыми членами класса Area.
Следующим используемым классом является «printClass», который печатает площадь, вычисленную функцией calcArea в классе Area. Поскольку члены являются закрытыми, нам нужно сделать printClass другом класса Area.
После этого в основной функции мы создаем объект класса Area, вычисляем площадь и передаем объект в функцию printArea класса printClass для отображения площади.
Преимущества и недостатки дружественной функции или класса
Одним из преимуществ дружественной функции или класса является то, что мы можем получить доступ к закрытым и защищенным данным класса. Например, если мы реализуем связанный список, то мы можем сделать класс связанного списка другом класса узла и получить доступ к его данным, поскольку связанный список состоит из узлов.
Таким образом, в определенной ситуации использование дружественной функции или класса может оказаться выгодным. Однако у нее есть и некоторые недостатки.
Одной из отличительных особенностей C++ является инкапсуляция, т.е. объединение данных и функций, работающих с этими данными, вместе, так что никакая внешняя функция или класс не могут получить доступ к данным. Но, разрешая дружественным функциям или классу доступ к закрытым членам другого класса, мы фактически ставим под угрозу функцию инкапсуляции.
Чтобы предотвратить это, мы должны быть осторожны при использовании дружественных функций или классов. Нужно следить за тем, чтобы в программе не использовалось слишком много дружественных функций и классов, что полностью поставит под угрозу инкапсуляцию.
Итог
На этом мы завершаем нашу статью про дружественные функции и классы в C++.
Помните, вы должны быть очень осторожны при использовании дружественных классов и функций, так как это может послужить лазейкой для хакера. Их также нужно использовать осторожно, поскольку чрезмерное использование дружественных функций и классов может поставить под угрозу функцию инкапсуляции ООП в программе.
В нашей следующей статье мы подробно расскажем о важности и использовании ключевого слова static в C++, а также приведем соответствующие примеры.
С Уважением, МониторБанк