Дружественные функции - это функции, которые не являются членами класса, однако имеют доступ к его закрытым членам - переменным и функциям, которые имеют спецификатор private.
Для определения дружественных функций используется ключевое слово friend. Например, определим следующую программу:
Здесь определен класс Auto, который представляет автомобиль. У этого класса определены приватные закрытые переменные name (название автомобиля) и price (цена автомобиля). Также в классе объявлены две дружественные функции: drive (функция вождения автомобиля) и setPrice (функция назначения цены). Обе этих функции принимают в качестве параметра ссылку на объект Auto.
Когда мы объявляем дружественные функции, то фактически мы говорим компилятору, что это друзья класса и они имеют доступ ко всем членам этого класса, в том числе закрытым.
При этом для дружественных функций не важно, определяются они под спецификатором public или private. Для них это не имеет значения.
Определение этих функций производится вне класса. И поскольку эти функции являются дружественными, то внутри этих функций мы можем через переданную ссылку Auto обратиться ко всем его закрытым переменным.
Консольный вывод программы:
Tesla is driven
Tesla : 5000
Tesla : 8000
Определение дружественных функций в классе
Дружественные функции могут определяться в другом классе. Например, определим класс Person, который использует объект Auto:
#include <iostream>
#include <string>
class Auto;
class Person
{
public:
Person(std::string n)
{
name = n;
}
void drive(Auto &a);
void setPrice(Auto &a, int price);
private:
std::string name;
};
class Auto
{
friend void Person::drive(Auto &);
friend void Person::setPrice(Auto &, int price);
public:
Auto(std::string autoName, int autoPrice)
{
name = autoName;
price = autoPrice;
}
std::string getName() { return name; }
int getPrice() { return price; }
Объяснение:
1 void drive(Auto &a);
2 void setPrice(Auto &a, int price);
То есть фигурально говоря, человек водит автомобиль и назначает ему цену с этих функциий.
Класс Auto определяет дружественные функции с той же сигнатурой:
1 friend void Person::drive(Auto &);
2 friend void Person::setPrice(Auto &, int price);
Причем поскольку данные функции будут определены в классе Person, то названия этих функций предваряется префиксом "Person::".
И поскольку в этих функциях предполагается использовать объект Auto, то ко времени определения этих функций все члены объекта Auto должны быть известны, поэтому определения функций находятся не в самом классе Person, а после класса Auto. И так как эти функции определены в классе Auto как дружественные, мы можем обратиться в этих функциях к закрытым членам класса Auto.
Консольный вывод программы:
Tom drives Tesla
Tesla : 8000
Дружественные классы
В случае выше класс Person использует только две функции из класса Auto. Но допустим впоследствии возникла необходимость добавить в класс Auto еще ряд дружественных функций, которые будут определены в классе Person. Либо мы можем предполагать, что класс Person будет активно использовать объекты Auto. И в этом случае целесообразно определять не отдельные дружественные функции, а определить дружественным весь класс Person:
Дружественные функции - это функции, которые не являются членами класса, однако имеют доступ к его закрытым членам - переменным и функциям, которые имеют спецификатор private.
Для определения дружественных функций используется ключевое слово friend. Например, определим следующую программу:
#include <iostream>
#include <string>
class Auto
{
friend void drive(Auto &);
friend void setPrice(Auto &, int price);
public:
Auto(std::string autoName, int autoPrice)
{
name = autoName;
price = autoPrice;
}
std::string getName(){ return name; }
int getPrice() { return price; }
private:
std::string name; // название автомобиля
int price; // цена автомобиля
};
void drive(Auto &a)
{
std::cout << a.name << " is driven" << std::endl;
}
void setPrice(Auto &a, int price)
{
if (price > 0)
a.price = price;
}
int main()
{
Auto tesla("Tesla", 5000);
drive(tesla);
std::cout << tesla.getName() << " : " << tesla.getPrice() << std::endl;
setPrice(tesla, 8000);
std::cout << tesla.getName() << " : " << tesla.getPrice() << std::endl;
return 0;
}
Здесь определен класс Auto, который представляет автомобиль. У этого класса определены приватные закрытые переменные name (название автомобиля) и price (цена автомобиля). Также в классе объявлены две дружественные функции: drive (функция вождения автомобиля) и setPrice (функция назначения цены). Обе этих функции принимают в качестве параметра ссылку на объект Auto.
Когда мы объявляем дружественные функции, то фактически мы говорим компилятору, что это друзья класса и они имеют доступ ко всем членам этого класса, в том числе закрытым.
При этом для дружественных функций не важно, определяются они под спецификатором public или private. Для них это не имеет значения.
Определение этих функций производится вне класса. И поскольку эти функции являются дружественными, то внутри этих функций мы можем через переданную ссылку Auto обратиться ко всем его закрытым переменным.
Консольный вывод программы:
Tesla is driven
Tesla : 5000
Tesla : 8000
Определение дружественных функций в классе
Дружественные функции могут определяться в другом классе. Например, определим класс Person, который использует объект Auto:
#include <iostream>
#include <string>
class Auto;
class Person
{
public:
Person(std::string n)
{
name = n;
}
void drive(Auto &a);
void setPrice(Auto &a, int price);
private:
std::string name;
};
class Auto
{
friend void Person::drive(Auto &);
friend void Person::setPrice(Auto &, int price);
public:
Auto(std::string autoName, int autoPrice)
{
name = autoName;
price = autoPrice;
}
std::string getName() { return name; }
int getPrice() { return price; }
Объяснение:
1 void drive(Auto &a);
2 void setPrice(Auto &a, int price);
То есть фигурально говоря, человек водит автомобиль и назначает ему цену с этих функциий.
Класс Auto определяет дружественные функции с той же сигнатурой:
1 friend void Person::drive(Auto &);
2 friend void Person::setPrice(Auto &, int price);
Причем поскольку данные функции будут определены в классе Person, то названия этих функций предваряется префиксом "Person::".
И поскольку в этих функциях предполагается использовать объект Auto, то ко времени определения этих функций все члены объекта Auto должны быть известны, поэтому определения функций находятся не в самом классе Person, а после класса Auto. И так как эти функции определены в классе Auto как дружественные, мы можем обратиться в этих функциях к закрытым членам класса Auto.
Консольный вывод программы:
Tom drives Tesla
Tesla : 8000
Дружественные классы
В случае выше класс Person использует только две функции из класса Auto. Но допустим впоследствии возникла необходимость добавить в класс Auto еще ряд дружественных функций, которые будут определены в классе Person. Либо мы можем предполагать, что класс Person будет активно использовать объекты Auto. И в этом случае целесообразно определять не отдельные дружественные функции, а определить дружественным весь класс Person:
100
Объяснение:
так как а→b = ложь при а=истина, b = ложь (смотри прикрепленное изображение 1)
то в данном случае ¬(¬x∨y)→z = ложь при ¬(¬x∨y) = истина, z=ложь (0)
так как ¬а = истина при а = ложь (смотри прикрепленное изображение 2)
то в данном случае ¬(¬x∨y) = истина при ¬x∨y = ложь
так как a∨b = ложь при а = ложь и b = ложь (смотри прикрепленное изображение 3)
то в данном случае ¬x∨y = ложь при ¬x = ложь и y = ложь (0)
так как ¬а = ложь при а = истина (смотри прикрепленное изображение 2)
то в данном случае ¬x = ложь при х = истина (1)