Оцените презентацию от 1 до 5 баллов!
Тип файла:
ppt / pptx (powerpoint)
Всего слайдов:
21 слайд
Для класса:
1,2,3,4,5,6,7,8,9,10,11
Размер файла:
163.04 kB
Просмотров:
54
Скачиваний:
0
Автор:
неизвестен
Слайды и текст к этой презентации:
№1 слайд
Содержание слайда: 15 популярных вопросов
с IT-собеседований
по языку С++
Источник: https://proglib.io/p/tricky-challenges-cpp/
№2 слайд
Содержание слайда: 1 Что получим на выходе?
#include<iostream>
using namespace std;
int f();
int x = 9;
int main()
{ f();
cout << x;
}
int f()
{
::x = 8;
}
№3 слайд
Содержание слайда: 2 Что на выходе и почему?
int main(int argc, char **argv)
{
std::cout << 25u - 50;
return 0;
}
Ответ равен не -25,
Существует иерархия преобразования типов: long double, double, float, unsigned long int, long int, unsigned int, int.
Все операнды в выражении преобразуются к верхнему типу.
В выражении «25u (unsigned int) - 50 (int)» 50 будет преобразовано в безнаковое целое (в число 50u).
И полученный результат -25 тоже будет типа unsigned int, а именно будет равен 4294967271 (для 32-х битной системы).
№4 слайд
Содержание слайда: 3 Разберем код:
#include<iostream>
class D {
public:
void foo() { std::cout << "Foooooo" << std::endl; }
};
class C: public D {};
class B: public D {};
class A: public B, public C {};
int main() {
A a;
a.foo();
}
№5 слайд
Содержание слайда: 3 Когда используется виртуальное наследование?
Исправим:
#include<iostream>
class D {
public:
void foo() { std::cout << "Foooooo" << std::endl; }
};
class C: virtual public D {};
class B: virtual public D {};
class A: public B, public C {};
int main() {
A a;
a.foo();
}
№6 слайд
Содержание слайда: 4 Что означает модификатор virtual?
В C++ виртуальные функции позволяют поддерживать полиморфизм – одну из ключевых составляющих ООП. С его помощью в классах-потомках можно переопределять функции класса-родителя.
Без виртуальной функции мы получаем «раннее связывание», а с ней – «позднее связывание». То есть, какая реализация метода используется, определяется непосредственно во время выполнения программы и основывается на типе объекта с указателем на объект, из которого он построен.
№7 слайд
Содержание слайда: 5 Пример использования виртуальной функции
class Animal
{ public:
void eat() { std::cout << "I'm eating generic food."; }
};
class Cat : public Animal
{ public:
void eat() { std::cout << "I'm eating a rat."; }
};
main()
{ Animal *animal = new Animal;
Cat *cat = new Cat;
animal->eat();
cat->eat();
}
№8 слайд
Содержание слайда: 5 Пример использования виртуальной функции
Добавим функцию:
void func(Animal *xyz) { xyz->eat(); }
class Animal
{ public:
void eat() { std::cout << "I'm eating generic food."; }
};
class Cat : public Animal
{ public:
void eat() { std::cout << "I'm eating a rat."; }
};
main()
{ Animal *animal = new Animal;
Cat *cat = new Cat;
// вызовем eat() с использованием fun
func(animal);
func(cat);
}
№9 слайд
Содержание слайда: 5 Пример использования виртуальной функции
Исправим:
void func(Animal *xyz) { xyz->eat();
class Animal
{ public:
void virtual eat() { std::cout << "I'm eating generic food."; }
};
class Cat : public Animal
{ public:
void eat() { std::cout << "I'm eating a rat."; }
};
main()
{ Animal *animal = new Animal;
Cat *cat = new Cat;
// вызовем с использованием fun
func(animal);
func(cat);
}
№10 слайд
Содержание слайда: 6 Существует ли различие между классом и структурой?
Единственное различие между классом и структурой – это модификаторы доступа.
Элементы структуры являются общедоступными по умолчанию – public, а элементы класса – private.
Рекомендуется использовать классы, когда вам нужен объект с методами, а иначе (простой объект) – структуры.
№11 слайд
Содержание слайда: 7 Что не так с кодом?
class A
{ public:
A() {}
~A(){ }
};
class B: public A
{ public:
B():A(){}
~B(){ }
};
int main(void)
{ A* a = new B();
delete a;
}
№12 слайд
Содержание слайда: 7 Что не так с кодом?
Удаление объекта порожденного класса через указатель на базовый класс без виртуального деструктора (virtual ~) является неопределенным поведением (undefined behavior) согласно стандарту C++11 §5.3.5/3.
Вызов деструктора порожденного класса может работать, а может и нет, и нет никаких гарантий -> избегать такого.
№13 слайд
Содержание слайда: 8 Что такое класс хранения?
Класс, который определяет срок существования, компоновку и расположение переменных/функций в памяти.
В C ++ поддерживаются такие классы хранения:
auto,
static,
register,
extern,
mutable.
Обратите внимание, что register устарел для C++11. Для C++17 он был удален и зарезервирован для будущего использования.
№14 слайд
Содержание слайда: 9 Как вызвать функцию C в программе на C++?
//C code
void func(int i)
{
//code
}
void print(int i)
{
//code
}
Соглашение о вызове:
в С и С++ параметры передаются по разному (используя регистры и стек, но каждый по-своему).
№15 слайд
Содержание слайда: 10 Что делает ключевое слово const?
Задает константность объекта, указателя, а также указывает, что данный метод сохраняет состояние объекта (не модифицирует члены класса).
Пример с неизменяемыми членами класса:
class Foo
{
private:
int i;
public:
void func() const
{ i = 1;
}
};
№16 слайд
Содержание слайда: 11 Виртуальный деструктор: что он собой представляет?
Во-первых, он объявляется как virtual. Он нужен, чтобы с удалением указателя на какой-нибудь объект был вызван деструктор данного объекта.
Например, у нас есть 2 класса:
class base
{ public:
~base()
{ cout<<"destructor base\n";
}
};
class derived: public base
{ public:
~derived()
{ cout << "destructor derived\n";
}
};
№17 слайд
Содержание слайда: 11 Виртуальный деструктор: что он собой представляет?
Без виртуального деструктора будет выполняться только вызов деструктора базового класса, а вызов производного деструктора - не будет. Получаем «утечку памяти».
Поэтому необходимо деструктор базового класса сделать виртуальным (добавить virtual), тогда освобождение памяти будет корректным.
№18 слайд
Содержание слайда: 12 Виртуальный конструктор: что он собой представляет?
Каверзный вопрос с IT-собеседований, который чаще всего задают именно после виртуальных деструкторов, дабы сбить кандидата с толку.
Конструктор не может быть виртуальным, поскольку в нем нет никакого смысла: при создании объектов нет такой неоднозначности, как при их удалении.
№19 слайд
Содержание слайда: 13. Сколько раз будет выполняться этот цикл?
unsigned char half_limit = 150;
for (unsigned char i = 0; i < 2 * half_limit; ++i)
{ //что-то происходит;
}
Еще один вопрос с подвохом с IT-собеседований.
Ответ был бы равен 300, если бы i был объявлен как int.
Но поскольку i объявлен как unsigned char, правильный ответ – зацикливание (бесконечный цикл).
Выражение 2 * half_limit будет повышаться до int (на основе правил преобразования C++) и получит значение 300. Но так как i – это unsigned char, он пересматривается по 8-битному значению, которое после достижения 255 будет переполняться, поэтому вернется к 0, и цикл будет продолжаться вечно.
№20 слайд
Содержание слайда: 14. Каков результат следующего кода?
#include<iostream>
class Base {
virtual void method() {std::cout << "from Base" << std::endl;}
public:
virtual ~Base() {method();}
void baseMethod() {method();}
};
class A : public Base {
void method() {std::cout << "from A" << std::endl;}
public:
~A() {method();}
};
int main(void) {
Base* base = new A;
base->baseMethod();
delete base;
return 0;
}
№21 слайд
Содержание слайда: 15. Что мы получим на выходе?
#include <iostream>
int main() {
int a[] = {1, 2, 3, 4, 5, 6};
std::cout << (1 + 3)[a] - a[0] + (a + 1)[2];
}
Ответ равен 8
(1 + 3)[a] – то же, что и a[1 + 3] == 5
a[0] == 1
(a + 1)[2] – то же, что и a[3] == 4
Суть вопроса заключается в проверке арифметических знаний и понимании всей магии, которая происходит за квадратными скобками.