Ответы на вопросы для собеседования C++ разработчика
Какой код выполняется до main?
Конструкторы глобальных объектов.
Как вызвать функцию C в коде C++?
Это возможно, если использовать extern «C»
:
//C code
void func(int i)
{
//code
}
void print(int i)
{
//code
}
//C++ code
extern "C"{
void func(int i);
void print(int i);
}
void myfunc(int i)
{
func(i);
print(i);
}
Что такое указатель?
Указатель — это переменная, которая хранит адрес памяти объекта. Указатели широко используются в C и C++ для трех основных целей: 1. Для выделения новых объектов в куче, 2. Для передачи функций другим функциям 3. Для итерации элементов в массивах или других структурах данных.
Раскажите про ключевое слово const
1. Позволяет задать константность объекта
2. Позволяет задать константность указателя
3. Позволяет указать, что данный метод не модифицирует члены класса, т.е. сохраняет состояние объекта
Не можем изменить значение объекта:
const int i = 1;
i = 2; // error C3892: 'i' : you cannot assign to a variable that is const
Не можем изменить указатель на объект:
int i = 1;
int* const j(&i);
int k = 2;
*j = k; // Ok
j = &k; // error C3892: 'j' : you cannot assign to a variable that is const
Не можем изменить члены класса:
class Foo
{
private:
int i;
public:
void func() const
{
i = 1; // error C3490: 'i' cannot be modified because it is being accessed through a const object
}
};
Дополнение: константный метод может изменять члены класса, если они объявлены как mutable
.
Как запретить копирование объекта?
Для того, чтобы запретить копирование объекта, нужно сделать private
конструктор копирования и оператор =
.
class NonCopyable
{
public:
NonCopyable(){}
private:
NonCopyable(NonCopyable&){}
private:
void operator=(const NonCopyable&){}
};
NonCopyable a;
NonCopyable b = a; // error C2248: 'NonCopyable::NonCopyable' : cannot access private member
a = b; // error C2248: 'NonCopyable::operator =' : cannot access private member
Зачем нужен модификатор virtual?
В C++ виртуальные функции позволяют поддерживать полиморфизм – одну из ключевых составляющих ООП. С его помощью в классах-потомках можно переопределять функции класса-родителя. Без виртуальной функции мы получаем «раннее связывание», а с ней – «позднее». То есть, какая реализация метода используется, определяется непосредственно во время выполнения и основывается на типе объекта с указателем на объект, из которого он построен.
Что такое чисто виртуальный метод и абстрактный класс?
// Абстрактный класс
class Foo
{
public:
// Чисто виртуальный метод
virtual void func() = 0;
};
class Bar : public Foo
{
public:
virtual void func()
{
}
};
Foo f; // error C2259: 'Foo' : cannot instantiate abstract class
Bar b; // Ok
Чисто виртуальный метод — это метод, у которого отсутствует реализация.
Абстрактный класс — это класс, имеющий хотя бы один чисто виртуальный метод. Как следствие, экземпляр подобного класса не может быть создан т. к. отсутствует реализация виртуального метода.
Что такое виртуальный деструктор?
Чтобы избежать возможной утечки ресурсов или другого неконтролируемого поведения объекта, в логику работы которого включен вызов деструктора.
Пример:
class Base
{
public:
virtual ~Base()
{
std::cout << "Hello from ~Base()" << std::endl;
}
};
class Derived : public Base
{
public:
virtual ~Derived()
{
// Здесь могла бы быть очистка ресурсов
std::cout << "Hello from ~Derived()" << std::endl;
}
};
Base *obj = new Derived();
delete obj;
Вывод:
Hello from ~Derived()
Hello from ~Base()
Без ключевого слова virtual
у родительского класса Base
деструктор порожденного класса не был бы вызван. Т.е. вызвался бы только ~Base()
.
Что такое виртуальный конструктор?
Каверзный вопрос, который чаще всего задают именно после виртуальных деструкторов, дабы сбить кандидата с толку. Конструктор не может быть виртуальным, поскольку в нем нет никакого смысла: при создании объектов нет такой неоднозначности, как при их удалении.