1. Есть класс A. Создайте класс B, который является наследником класса A.
2. Создайте экземпляры классов A и B в динамической памяти (куче):
3. Пусть есть кусок кода на C++, оперирующий с классами из задачи 1:
A* a = new A;
B* b = new B;
a = b; // (1)
b = a; // (2)
Что произойдет? Скомпилится/не скомпилится, будет работать или нет? Почему? Какой модификатор наследования может повлиять на результат?
4. Есть класс A с перегруженным оператором постфиксного и префиксного инкремента. Сколько раз и какой конструктор класса A будет вызван в следующем коде:
A*a;
a++;
5. Назовите 5 контейнеров из стандартной библиотеки
6. Какие контейнеры из SNL могут обеспечить логарифмическое время поиска по значению элемента?
7. Какие контейнеры могут обеспечить константное время доступа к элементу?
наш чат бэкендеров
Решение: 1. class A {};
class B : public A {};
2. A* objA = new A();
B* objB = new B();
3. (1) a = b;
Скомпилируется и будет работать, так как указатель на производный класс (B*) может быть неявно преобразован в указатель на базовый класс (A*). Это безопасное преобразование.
(2) b = a;
Не скомпилируется, так как указатель на базовый класс (A*) не может быть неявно преобразован в указатель на производный класс (B*) без явного приведения (например, dynamic_cast). Это может привести к ошибкам, если a не указывает на объект типа B.
Влияние модификатора наследования:
Если наследование будет private или protected, то преобразование A* a = b; станет невозможным вне класса B или его друзей. Например: class B : private A {};
A* a = b; // Ошибка компиляции: недоступно из-за private наследования.
4. В данном коде a — это указатель, а не объект класса A. Оператор ++ применяется к указателю и не вызывает никаких конструкторов класса A. Это стандартная арифметика указателей.
Если бы a был объектом (например, A a;), то:
Префиксный инкремент: ++a вызывает A& operator++().
Постфиксный инкремент: a++ вызывает A operator++(int) (создает временный объект, вызывая конструктор копирования).
5. Кек
6. Еще больший кек
7. тоже рофл
@codeof_art