2. rebase: перемещает изменения текущей ветки поверх другой, переписывая историю. Это делает историю линейной и более чистой, но может привести к конфликтам и проблемам при совместной работе.
merge используется для сохранения полной истории, а rebase — для её упрощения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍4💊2
IntegerChoices
в Django используется для создания выбора из ограниченного набора целочисленных значений для поля модели. Это полезно, когда вам нужно ограничить допустимые значения для поля модели определенными целыми числами, и при этом иметь удобные человекочитаемые названия для этих значений.Значения выбора имеют человекочитаемые названия, что делает код более понятным.
Django автоматически проверяет, что значение поля соответствует одному из допустимых значений.
В Django admin интерфейсе выпадающий список с человекочитаемыми названиями делает работу с данными удобнее.
IntegerChoices
from django.db import models
class Status(models.IntegerChoices):
PENDING = 1, 'Pending'
APPROVED = 2, 'Approved'
REJECTED = 3, 'Rejected'
IntegerChoices
в моделиfrom django.db import models
class Application(models.Model):
status = models.IntegerField(choices=Status.choices, default=Status.PENDING)
name = models.CharField(max_length=100)
submitted_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.name} - {self.get_status_display()}"
# Создание новой записи
app = Application.objects.create(name='John Doe')
# Проверка статуса
print(app.status) # 1
print(app.get_status_display()) # 'Pending'
# Изменение статуса
app.status = Status.APPROVED
app.save()
# Проверка обновленного статуса
print(app.status) # 2
print(app.get_status_display()) # 'Approved'
Вы можете добавлять дополнительные методы и атрибуты в класс выбора для расширенной функциональности.
from django.db import models
class Status(models.IntegerChoices):
PENDING = 1, 'Pending'
APPROVED = 2, 'Approved'
REJECTED = 3, 'Rejected'
@classmethod
def get_choices(cls):
return [(choice.value, choice.label) for choice in cls]
# Пример использования
print(Status.get_choices()) # [(1, 'Pending'), (2, 'Approved'), (3, 'Rejected')]
Использование в фильтрах и запросах
# Фильтрация записей по статусу
pending_apps = Application.objects.filter(status=Status.PENDING)
for app in pending_apps:
print(app.name)
# Фильтрация записей по множеству статусов
approved_or_rejected_apps = Application.objects.filter(status__in=[Status.APPROVED, Status.REJECTED])
for app in approved_or_rejected_apps:
print(app.name)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤1💊1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍3
В Django существует несколько вариантов определения модели пользователя. По умолчанию Django предоставляет базовую модель пользователя, но если требуется кастомизация, можно создать свою модель пользователя.
Django предоставляет стандартную модель пользователя через
django.contrib.auth.models.User
. Эта модель включает в себя все основные поля и методы для работы с пользователями.from django.contrib.auth.models import User
# Создание нового пользователя
user = User.objects.create_user(username='john', password='password123')
# Аутентификация пользователя
from django.contrib.auth import authenticate, login
user = authenticate(username='john', password='password123')
if user is not None:
login(request, user)
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(blank=True)
birth_date = models.DateField(null=True, blank=True)
# Сигналы для автоматического создания и сохранения профиля пользователя
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.userprofile.save()
# Получение и изменение профиля пользователя
user = User.objects.get(username='john')
profile = user.userprofile
profile.bio = "Hello, I'm John!"
profile.save()
Если необходимо полностью изменить модель пользователя, можно создать кастомную модель пользователя и указать Django использовать её вместо стандартной.
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models
class CustomUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError('The Email field must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
return self.create_user(email, password, **extra_fields)
class CustomUser(AbstractBaseUser):
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=30, blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = CustomUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']
def __str__(self):
return self.email
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤1
QuerySet в Django является ленивым, что означает, что запросы к базе данных выполняются только при необходимости (например, при итерации или вызове методов вроде .all() или .filter()). Это позволяет оптимизировать работу с данными и предотвращать лишние запросы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥6
Это механизм, который позволяет программам обмениваться данными по сети. Они являются одним из основных способов коммуникации между устройствами в сетях, таких как интернет или локальная сеть (LAN). Сокеты используются для реализации различных сетевых протоколов, таких как TCP (Transmission Control Protocol) и UDP (User Datagram Protocol).
Сокеты используются для связи между двумя устройствами по сети, такие как клиент и сервер.
TCP-сокеты (стриминговые сокеты): Обеспечивают надежное, установочное соединение с проверкой целостности данных и управлением потоком. Пример использования — веб-серверы и клиенты.
UDP-сокеты (датаграммные сокеты): Обеспечивают безустановочное соединение с меньшей задержкой, но без гарантии доставки данных. Пример использования — видеостриминг, игры в реальном времени.
TCP-сокеты
Сервер
import socket
# Создание TCP-сокета
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Привязка сокета к адресу и порту
server_socket.bind(('localhost', 12345))
# Ожидание входящих соединений
server_socket.listen()
print('Сервер ожидает соединения...')
while True:
# Принятие нового соединения
client_socket, client_address = server_socket.accept()
print(f'Подключение от {client_address}')
# Получение данных от клиента
data = client_socket.recv(1024).decode()
print(f'Получено: {data}')
# Отправка ответа клиенту
client_socket.sendall('Hello, Client!'.encode())
# Закрытие соединения
client_socket.close()
Клиент
import socket
# Создание TCP-сокета
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Подключение к серверу
client_socket.connect(('localhost', 12345))
# Отправка данных серверу
client_socket.sendall('Hello, Server!'.encode())
# Получение ответа от сервера
data = client_socket.recv(1024).decode()
print(f'Получено: {data}')
# Закрытие соединения
client_socket.close()
UDP-сокеты
Сервер
import socket
# Создание UDP-сокета
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Привязка сокета к адресу и порту
server_socket.bind(('localhost', 12345))
print('UDP сервер ожидает сообщений...')
while True:
# Получение данных от клиента
data, client_address = server_socket.recvfrom(1024)
print(f'Получено от {client_address}: {data.decode()}')
# Отправка ответа клиенту
server_socket.sendto('Hello, Client!'.encode(), client_address)
Клиент
import socket
# Создание UDP-сокета
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Отправка данных серверу
client_socket.sendto('Hello, Server!'.encode(), ('localhost', 12345))
# Получение ответа от сервера
data, server_address = client_socket.recvfrom(1024)
print(f'Получено: {data.decode()}')
# Закрытие сокета
client_socket.close()
Сокеты предоставляют низкоуровневый доступ к сетевым операциям, позволяя разрабатывать различные сетевые протоколы.
Обеспечивают надежную передачу данных с управлением потоком и проверкой целостности.
Позволяют быстро передавать данные с минимальной задержкой.
Работа с сокетами требует понимания сетевых протоколов и управления соединениями.
Данные могут теряться или приходить в неправильном порядке.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥2
Метод
__call__
является специальным методом, который позволяет экземплярам классов вести себя как функции. Если объект класса имеет данный метод, то этот объект можно вызывать, как если бы он был функцией. Это может быть полезно для создания объектов, которые действуют как замыкания, для реализации паттернов проектирования и других сценариев, требующих функциональности.Позволяет объекту вести себя как функция. Он вызывается, когда экземпляр класса вызывается как функция.
class Counter:
def __init__(self):
self.count = 0
def __call__(self):
self.count += 1
return self.count
# Использование
counter = Counter()
print(counter()) # Вывод: 1
print(counter()) # Вывод: 2
print(counter()) # Вывод: 3
Позволяет создавать объекты, которые можно вызывать как функции, что полезно для создания замыканий и функций высшего порядка.
Используется для реализации механизмов кеширования в классах, когда результат вычисления может быть закеширован и повторно использован.
class Multiplier:
def __init__(self, factor):
self.factor = factor
def __call__(self, value):
return value * self.factor
# Использование
double = Multiplier(2)
triple = Multiplier(3)
print(double(5)) # Вывод: 10
print(triple(5)) # Вывод: 15
Пример кеширования
class CachedFibonacci:
def __init__(self):
self.cache = {}
def __call__(self, n):
if n in self.cache:
return self.cache[n]
if n <= 1:
return n
self.cache[n] = self(n - 1) + self(n - 2)
return self.cache[n]
# Использование
fibonacci = CachedFibonacci()
print(fibonacci(10)) # Вывод: 55
print(fibonacci(15)) # Вывод: 610
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤4💊1
Это структура данных, которая хранит пары ключ-значение и использует хеш-функцию для вычисления индекса.
Хеширование: ключ преобразуется в числовое значение (хеш).
Размещение: хеш определяет индекс, куда сохраняется значение.
Коллизии: если два ключа имеют одинаковый хеш, используется метод разрешения коллизий (связанный список, открытая адресация).
Хеш-таблицы обеспечивают быстрый доступ (O(1)) к данным при правильной реализации.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤1
Это компактный, URL-безопасный способ представления заявок между двумя сторонами. JWT широко используется для аутентификации и авторизации в веб-приложениях.
JWT — это компактный формат, который легко передавать через URL, заголовки HTTP или внутри тела запроса.
JWT содержит всю необходимую информацию для проверки подлинности, что избавляет от необходимости обращаться к базе данных при каждом запросе.
JWT может быть подписан с использованием алгоритмов HMAC или RSA, что обеспечивает целостность и подлинность данных.
Заголовок обычно содержит два поля
Тип токена (
typ
), который для JWT равен "JWT".Алгоритм подписи (
alg
), например, HMAC SHA256 или RSA.{
"alg": "HS256",
"typ": "JWT"
}
Полезная нагрузка содержит набор заявок (claims). Заявки бывают трех типов: Registered claims (Зарегистрированные заявки): Зарезервированные ключи, такие как iss (issuer), exp (expiration time), sub (subject), и aud (audience).
Public claims (Публичные заявки): Пользовательские ключи, определенные в спецификации IANA JSON Web Token Registry или согласованные между сторонами.
Private claims (Частные заявки): Пользовательские ключи, уникальные для конкретного приложения.
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
Подпись создается путем кодирования заголовка и полезной нагрузки с использованием Base64URL и их объединения. Затем применяется алгоритм, указанный в заголовке, к объединенной строке с использованием секретного ключа.
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
pip install pyjwt
import jwt
import datetime
# Секретный ключ
secret_key = "your-256-bit-secret"
# Заголовок
header = {
"alg": "HS256",
"typ": "JWT"
}
# Полезная нагрузка
payload = {
"sub": "1234567890",
"name": "John Doe",
"admin": True,
"exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=30) # Время истечения действия токена
}
# Создание JWT
token = jwt.encode(payload, secret_key, algorithm="HS256", headers=header)
print(token)
import jwt
# Секретный ключ
secret_key = "your-256-bit-secret"
# Декодирование JWT
try:
decoded_payload = jwt.decode(token, secret_key, algorithms=["HS256"])
print(decoded_payload)
except jwt.ExpiredSignatureError:
print("Signature has expired")
except jwt.InvalidTokenError:
print("Invalid token")
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17
2. virtualenv: популярное расширение с дополнительными функциями для управления виртуальными окружениями.
3. conda: используется в научных вычислениях и анализе данных, управляет не только Python, но и библиотеками C/C++.
4. Poetry: создаёт и управляет зависимостями через автоматическое создание виртуальных окружений.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Методы getitem, setitem и delitem являются специальными методами, которые позволяют пользовательским объектам взаимодействовать с операциями получения, установки и удаления элементов по индексу или ключу. Эти методы обеспечивают интеграцию пользовательских классов с операциями индексирования, делая их поведение аналогичным встроенным типам данных, таким как списки и словари.
Используется для получения значения элемента по индексу или ключу. Он вызывается, когда используется оператор индексирования (
obj[key]
).class CustomList:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return self.items[index]
# Использование
my_list = CustomList([1, 2, 3, 4, 5])
print(my_list[2]) # Вывод: 3
Используется для установки значения элемента по индексу или ключу. Он вызывается, когда используется оператор присваивания с индексированием (
obj[key] = value
).class CustomList:
def __init__(self, items):
self.items = items
def __setitem__(self, index, value):
self.items[index] = value
# Использование
my_list = CustomList([1, 2, 3, 4, 5])
my_list[2] = 10
print(my_list.items) # Вывод: [1, 2, 10, 4, 5]
Используется для удаления элемента по индексу или ключу. Он вызывается, когда используется оператор удаления с индексированием (
del obj[key]
).class CustomList:
def __init__(self, items):
self.items = items
def __delitem__(self, index):
del self.items[index]
# Использование
my_list = CustomList([1, 2, 3, 4, 5])
del my_list[2]
print(my_list.items) # Вывод: [1, 2, 4, 5]
Полный пример пользовательского класса
class CustomDict:
def __init__(self):
self.items = {}
def __getitem__(self, key):
return self.items[key]
def __setitem__(self, key, value):
self.items[key] = value
def __delitem__(self, key):
del self.items[key]
def __repr__(self):
return f"{self.items}"
# Использование
my_dict = CustomDict()
my_dict['a'] = 1
my_dict['b'] = 2
print(my_dict['a']) # Вывод: 1
print(my_dict) # Вывод: {'a': 1, 'b': 2}
del my_dict['a']
print(my_dict) # Вывод: {'b': 2}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16❤1
1. Хеш-функция преобразует ключ в индекс массива.
2. Если возникают коллизии (два ключа дают одинаковый хеш), используются методы разрешения коллизий, например, цепочки (chaining) или открытая адресация.
3. В среднем сложность доступа — O(1), но может быть хуже при большом количестве коллизий.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥1
Методы
__enter__
и exit являются частью протокола менеджера контекста. Они позволяют объектам определять поведение в контексте оператора with
. Эти методы обеспечивают безопасное и автоматическое управление ресурсами, такими как файлы, сетевые соединения и другие объекты, которые требуют явного открытия и закрытия.Выполняется в начале блока
with
и возвращает объект, который будет присвоен переменной, указанной после as
.Выполняется в конце блока
with
, независимо от того, произошло исключение или нет. Он используется для очистки и освобождения ресурсов.class ManagedResource:
def __enter__(self):
print("Entering the context")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("Exiting the context")
if exc_type:
print(f"Exception type: {exc_type}")
print(f"Exception value: {exc_value}")
print(f"Traceback: {traceback}")
return True # True указывает на то, что исключение было обработано
# Использование
with ManagedResource() as resource:
print("Inside the context")
print("Outside the context")
Пример управления файлом с использованием менеджера контекста
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_value, traceback):
self.file.close()
if exc_type:
print(f"Exception type: {exc_type}")
print(f"Exception value: {exc_value}")
print(f"Traceback: {traceback}")
return True
# Использование
with FileManager("example.txt", "w") as f:
f.write("Hello, World!")
print("File operation completed")
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤1
2. Асинхронность: поддерживает async/await для обработки множества запросов одновременно.
3. Автогенерация документации: автоматически создаёт OpenAPI-спецификации и Swagger UI.
4. Удобство валидации: встроенная поддержка проверки данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17❤1
Наследование является мощным механизмом в ООП, но оно также может привести к ряду проблем, которые следует учитывать при проектировании и разработке программного обеспечения. Вот основные проблемы, связанные с наследованием:
Классы-наследники зависят от родительских классов. Изменения в родительских классах могут потребовать изменений в классах-наследниках. Если метод в родительском классе изменяет свою сигнатуру или поведение, все классы-наследники должны быть проверены и, возможно, изменены. Решение: Использование композиции вместо наследования, когда это возможно.
Изменения в базовом классе могут непредсказуемо повлиять на поведение классов-наследников. Добавление нового метода в базовый класс может конфликтовать с существующим методом в классе-наследнике. Решение: Ограничение изменений в базовом классе, тщательное проектирование и тестирование.
Может привести к конфликтам имен методов и атрибутов, а также к сложности разрешения порядка вызовов методов (MRO — Method Resolution Order). Если два родительских класса имеют методы с одинаковыми именами, класс-наследник может неясно указывать, какой метод использовать. Решение: Использование интерфейсов (в языках, поддерживающих интерфейсы) или композиций. В Python использовать миксины.
Классы-наследники наследуют все методы и атрибуты родительских классов, даже если они не нужны. Класс-наследник может быть перегружен ненужными методами и свойствами, которые ему не требуются. Решение: Использование композиции для включения только нужных функциональностей.
Классы-наследники могут получить доступ к защищённым (protected) и приватным (private) членам родительского класса, что может нарушить инкапсуляцию. Класс-наследник может изменить состояние родительского класса, вызывая неожиданные побочные эффекты. Решение: Строгое следование принципам инкапсуляции, использование методов доступа (геттеров и сеттеров).
class A:
def method(self):
print("Method from class A")
class B:
def method(self):
print("Method from class B")
class C(A, B):
pass
c = C()
c.method() # Вывод: Method from class A (MRO выбрал метод из класса A)
Предлагает включение объектов других классов в качестве членов, предоставляя больше гибкости и меньшую связанность по сравнению с наследованием.
class Engine:
def start(self):
print("Engine started")
class Car:
def __init__(self):
self.engine = Engine()
def start(self):
self.engine.start()
print("Car started")
car = Car()
car.start()
Могут помочь определить строгие контракты для классов-наследников без предоставления реализации.
Это классы, которые предназначены для предоставления дополнительной функциональности через множественное наследование, но они не предназначены для инстанцирования напрямую.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤2🤯1
2. HTTPS: расширение HTTP, использующее шифрование через SSL/TLS для защиты передаваемых данных.
3. HTTPS обеспечивает конфиденциальность, целостность данных и аутентификацию сервера.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16😁3🤯2
Это процесс определения порядка разрешения методов (Method Resolution Order, MRO), который используется для поиска методов и атрибутов в иерархии классов при множественном наследовании.
Python использует алгоритм C3-линеаризации для определения MRO. Если иерархия классов не соответствует принципам C3-линеаризации, то линеаризация невозможна.
Конфликты возникают, когда два или более родительских класса содержат методы или атрибуты с одинаковыми именами, и порядок их разрешения не может быть однозначно определён.
Если классы в иерархии имеют несовместимые или пересекающиеся зависимости, это может сделать линеаризацию невозможной.
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
Python использует C3-линеаризацию для определения порядка разрешения методов. Этот алгоритм соблюдает порядок наследования классов, учитывая при этом принципы монотонности и консистентности.
class A:
def method(self):
print("A")
class B(A):
def method(self):
print("B")
class C(A):
def method(self):
print("C")
class D(B, C):
pass
d = D()
d.method() # Вывод: B
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤1
1. Асинхронные операции позволяют выполнять другие задачи, пока ожидается завершение медленных операций, таких как запросы к сети или доступ к файлам.
2. Async используется с await для управления асинхронным кодом.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Это специальный метод, который вызывается при создании нового экземпляра класса. В языках ООП конструкторы используются для инициализации объектов, устанавливая начальные значения атрибутов и выполняя любые необходимые действия при создании экземпляра.
Называется
__init__
. Этот метод вызывается автоматически при создании нового объекта класса и используется для инициализации атрибутов объекта.class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def display(self):
print(f"Name: {self.name}, Age: {self.age}")
# Создание экземпляра класса Person
person1 = Person("Alice", 30)
person1.display() # Вывод: Name: Alice, Age: 30
person2 = Person("Bob", 25)
person2.display() # Вывод: Name: Bob, Age: 25
Инициализирует атрибуты объекта начальными значениями.
Может выполнять любые действия, необходимые при создании объекта (например, проверка входных данных).
Может выполнять действия по управлению ресурсами, такие как открытие файлов или подключение к базе данных.
Перегрузка конструктора не поддерживается напрямую, но можно использовать аргументы по умолчанию или конструкцию
args
и kwargs
для имитации перегрузки.#include <iostream>
using namespace std;
class Person {
public:
string name;
int age;
// Конструктор по умолчанию
Person() {
name = "Unknown";
age = 0;
}
// Конструктор с параметрами
Person(string n, int a) {
name = n;
age = a;
}
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
Person person1;
person1.display(); // Вывод: Name: Unknown, Age: 0
Person person2("Alice", 30);
person2.display(); // Вывод: Name: Alice, Age: 30
return 0;
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8