tgindex

C/C++ | Вопросы собесов

описание

Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @easyoffer_adv

4 179
подписчиков
Охват к подписчикам
9,9%
ERR
Реакции к просмотрам
0,13%
26 на 40 постов
Пересылки к просмотрам
0,45%
87
Постов в день
2,0
всего 37

Где отзываются чаще

доля реакций к просмотрам
  • 8 авг.🤔 Что такое POD тип ? POD (Plain Old Data) тип — это простой тип данных в C++, который совместим с C и обладает определенными свойствами, делающими его поведение предсказуемым и простым. 🚩Основные характеристики POD типов 🟠Тривиальность (Trivial) Тривиальный конструктор (конструктор по умолчанию, копирования и перемещения). Тривиальный деструктор. Компилятор генерирует их автоматически, если они не определены явно. 🟠Стандартная макетируемость (Standard Layout) Все нестатические члены данных имеют один и тот же доступ (public, private, или protected). Нет виртуальных функций и нет виртуальных базовых классов. Все базовые классы являются POD типами. Стандартные правила выравнивания и макетирования данных в памяти. struct MyPOD { int x; float y; }; Пример НЕ POD типа struct NonPOD { int x; virtual void func() {} // Наличие виртуальной функции делает тип не POD }; 🚩Применение POD типов 🟠Совместимость с C Поскольку POD типы совместимы с C, они могут быть безопасно использованы в смешанных C/C++ программах. 🟠Серилизация Легко сохранять и загружать из файлов или передавать по сети, так как их память может быть прочитана или записана напрямую. 🟠Оптимизация Компиляторы могут лучше оптимизировать код с POD типами из-за их простоты и предсказуемости. 🚩Проверка, является ли тип POD В C++11 и новее можно использовать стандартную библиотеку для проверки, является ли тип POD #include <type_traits> struct MyPOD { int x; float y; }; struct NonPOD { int x; virtual void func() {} }; int main() { std::cout << std::is_pod<MyPOD>::value << std::endl; // вывод: 1 (true) std::cout << std::is_pod<NonPOD>::value << std::endl; // вывод: 0 (false) return 0; } Ставь 👍 и забирай 📚 Базу знаний0,81%
  • 6 авг.🤔 Почему по идее в конструкторе нужны исключения? Необходимы для того, чтобы сигнализировать о неудачной инициализации объекта. Если инициализация объекта не может быть завершена успешно, конструктор должен сообщить об этом, чтобы предотвратить дальнейшее использование объекта в некорректном состоянии. 🟠Гарантия корректного состояния объекта Конструктор должен гарантировать, что объект находится в корректном состоянии после его создания. Если возникает ошибка при инициализации, использование объекта в некорректном состоянии может привести к непредсказуемым результатам и трудноотлаживаемым ошибкам. Если подключение к базе данных не удалось, исключение сигнализирует о неудачной инициализации. class DatabaseConnection { public: DatabaseConnection(const std::string& connectionString) { if (!connect(connectionString)) { throw std::runtime_error("Connection failed"); } } private: bool connect(const std::string& connectionString) { // Логика подключения return false; // Имитация ошибки подключения } }; 🟠Безопасность ресурсов Конструкторы часто выделяют ресурсы, такие как память, файлы или сетевые соединения. Если инициализация не удалась, необходимо убедиться, что все выделенные ресурсы будут корректно освобождены. Исключения помогают автоматизировать этот процесс, используя RAII (Resource Acquisition Is Initialization). Если файл не удалось открыть, исключение будет выброшено, и деструктор корректно освободит ресурсы. class FileHandler { public: FileHandler(const std::string& filename) { file = fopen(filename.c_str(), "r"); if (!file) { throw std::runtime_error("Failed to open file"); } } ~FileHandler() { if (file) { fclose(file); } } private: FILE* file; }; 🟠Целостность программы Исключения в конструкторах позволяют предотвратить использование некорректно инициализированных объектов. Это важно для поддержания целостности программы и избежания непредсказуемых ошибок. Если загрузка конфигурации не удалась, исключение предотвращает создание некорректного объекта ConfigLoader. class ConfigLoader { public: ConfigLoader(const std::string& configPath) { if (!loadConfig(configPath)) { throw std::runtime_error("Failed to load config"); } } private: bool loadConfig(const std::string& configPath) { // Логика загрузки конфигурации return false; // Имитация ошибки загрузки } }; 🚩Обработка исключений в конструкторах Исключения в конструкторах должны быть обработаны на более высоком уровне программы, чтобы гарантировать корректное завершение программы или повторение попытки инициализации. В этом примере ошибка инициализации обрабатывается в main, что позволяет программе корректно завершить работу или предпринять другие действия. int main() { try { DatabaseConnection db("connection_string"); } catch (const std::exception& e) { std::cerr << "Initialization failed: " << e.what() << std::endl; // Дополнительные действия по обработке ошибки } return 0; } Ставь 👍 и забирай 📚 Базу знаний0,61%
  • 13 авг.🤔 Какое присваивание разрешает unique_ptr? unique_ptr поддерживает только перемещение (move assignment), чтобы гарантировать уникальное владение объектом, но не копирование. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний0,56%
  • 10 авг.🤔 Что можешь рассказать о little-endian и big-endian? Little-endian и big-endian — это порядки байтов в мультибайтовых данных, используемые в компьютерной архитектуре для хранения данных. В little-endian младший байт сохраняется по низкому адресу, а старший байт по высокому. В big-endian старший байт сохраняется по низкому адресу, а младший по высокому. Выбор порядка байтов влияет на совместимость и производительность системы в различных сценариях использования. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний0,47%
  • 11 авг.🤔 В каком стандарте появился override? Ключевое слово override было введено в стандарт C++11. До его появления разработчики не могли явно указывать, что метод должен переопределять виртуальный метод базового класса. Это приводило к ошибкам, если сигнатура метода в базовом классе менялась или имя метода было неправильно написано. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний0,41%
  • 15 авг.без подписи0,35%
  • 15 авг.🤔 Какие есть тонкости при вызове виртуальной функции из конструктора или деструктора? Вызов виртуальных функций из конструктора или деструктора в C++ может привести к неожиданным результатам, поскольку полиморфизм в этих контекстах работает иначе. Рассмотрим эти тонкости подробнее. 🚩Поведение виртуальных функций в конструкторах и деструкторах 🟠Конструкторы Виртуальные функции в конструкторах вызываются в контексте текущего класса, а не в контексте производного класса. Когда конструктор базового класса вызывает виртуальную функцию, будет вызвана версия этой функции из самого базового класса, даже если объект принадлежит производному классу. Это связано с тем, что в момент вызова конструктора объект еще не полностью сконструирован как объект производного класса. 🟠Деструкторы Виртуальные функции в деструкторах также вызываются в контексте текущего класса. Когда деструктор базового класса вызывает виртуальную функцию, будет вызвана версия этой функции из самого базового класса, поскольку деструкторы вызываются в порядке от производного к базовому, и в момент вызова деструктора базового класса объект уже не является объектом производного класса. 🚩Пример для иллюстрации #include <iostream> class Base { public: Base() { std::cout << "Base constructor\n"; // Вызов виртуальной функции из конструктора this->virtualFunction(); } virtual ~Base() { std::cout << "Base destructor\n"; // Вызов виртуальной функции из деструктора this->virtualFunction(); } virtual void virtualFunction() { std::cout << "Base virtualFunction\n"; } }; class Derived : public Base { public: Derived() { std::cout << "Derived constructor\n"; } ~Derived() override { std::cout << "Derived destructor\n"; } void virtualFunction() override { std::cout << "Derived virtualFunction\n"; } }; int main() { Derived d; return 0; } 🤔 Вывод программы: Base constructor Base virtualFunction Derived constructor Derived destructor Base destructor Base virtualFunction Ставь 👍 и забирай 📚 Базу знаний0,35%
  • 18 авг.Дачная дача в Т-Банк Шопе Футболки с огурцами, тыквами, капустой и другие крутые штуки, да еще и с финансовыми пожеланиями. Надо брать. Посмотреть каталог #реклама tbank.ru О рекламодателе0,33%
  • 20 апр. 2025 г.🤔 Какой имеется побочный эффект при работе с кодом в хидере? При работе с кодом в хидерах возможны проблемы, связанные с повторным включением файлов (multiple inclusion), что может вызвать ошибки компиляции. Это решается использованием включающих защит (#pragma once или #ifndef). Также код в хидере увеличивает время компиляции, так как включается в несколько исходных файлов. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний0,30%
  • 8 янв.🤔 Какой имеется побочный эффект при работе с кодом в хидере? При работе с кодом в хидерах возможны проблемы, связанные с повторным включением файлов (multiple inclusion), что может вызвать ошибки компиляции. Это решается использованием включающих защит (#pragma once или #ifndef). Также код в хидере увеличивает время компиляции, так как включается в несколько исходных файлов. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний0,28%
  • 6 авг.🤔 Как сделать так, чтобы в shared_ptr были утечки? Утечки возможны при создании циклических ссылок, например, когда два объекта хранят shared_ptr друг на друга. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний0,22%
  • 4 авг.🤔 Для чего может применяться в С++ виртуальное наследование? Виртуальное наследование применяется для решения проблемы "ромбовидного наследования" (или "diamond problem"), которая возникает в иерархиях классов с множественным наследованием. Это проблема возникает, когда класс наследуется от двух классов, которые в свою очередь наследуются от одного общего базового класса. В результате создаются две копии базового класса в наследнике, что приводит к неоднозначностям и увеличению использования памяти. #include <iostream> class A { public: void show() { std::cout << "Class A" << std::endl; } }; class B : public A {}; class C : public A {}; class D : public B, public C {}; int main() { D obj; // obj.show(); // Ошибка: неоднозначность, show() есть и в B, и в C return 0; } 🚩Решение проблемы с использованием виртуального наследования Виртуальное наследование решает эту проблему, гарантируя, что в иерархии будет только одна копия базового класса. Это достигается с помощью ключевого слова virtual при наследовании. #include <iostream> class A { public: void show() { std::cout << "Class A" << std::endl; } }; class B : virtual public A {}; class C : virtual public A {}; class D : public B, public C {}; int main() { D obj; obj.show(); // Корректно: вызов метода show() из A return 0; } 🚩Как работает виртуальное наследование 🟠Одна копия базового класса При виртуальном наследовании в наследуемом классе создается только одна копия базового класса, независимо от того, сколько раз он виртуально наследуется. 🟠Оптимизация памяти Виртуальное наследование предотвращает создание множества копий базового класса, что экономит память. 🟠Явное разрешение неоднозначности Виртуальное наследование устраняет неоднозначности, связанные с вызовом методов и доступом к членам базового класса. 🟠Пример с конструкторами При виртуальном наследовании конструкторы базовых классов вызываются инициализирующим классом. #include <iostream> class A { public: A() { std::cout << "Constructor of A" << std::endl; } }; class B : virtual public A { public: B() { std::cout << "Constructor of B" << std::endl; } }; class C : virtual public A { public: C() { std::cout << "Constructor of C" << std::endl; } }; class D : public B, public C { public: D() { std::cout << "Constructor of D" << std::endl; } }; int main() { D obj; // Вывод: Constructor of A, Constructor of B, Constructor of C, Constructor of D return 0; } Ставь 👍 и забирай 📚 Базу знаний0,20%