fbpx
30 marca 2018

Pytania rekrutacyjne 04.2018

Oto kwietniowa paczka pytań rekrutacyjnych z C++. W tym miesiącu na tapecie mamy Nowoczesny C++, czyli standardy C++11, C++14, C++17.

Niestety żadna uczelnia nie uczy o tych standardach, a przecież C++11 istnieje już 7 lat i jego znajomość jest wymagana przez ogromną większość pracodawców (na pewno wszystkich z Wrocławia).

 

1. Wskaż poprawne przypisania dla poniższego kodu:
enum class Colors {
    RED,
    BLUE,
    GREEN
};
  1. const auto & e = RED;
  2. const auto e = RED;
  3. auto e = Colors::RED;
  4. const auto e = Colors::RED;

Zakresowy typ wyliczeniowy, czyli enum class powoduje, że nazwy w nim zdefiniowane nie wyciekają poza jego zakres. Aby więc zainicjalizować zmienną odpowiednią wartością, musimy się do niej odnieść poprzez nazwę zakresu, czyli w tym przypadku Colors::

 

2. Która z metod zdefiniowanych w strukturze B nie skompiluje się?
struct A {
    virtual void foo() = 0;
    void dd() {}
};

struct B : A {
    void foo() override {}
    void bar() override {}
    void dd() override {}
};
  1. foo()
  2. bar()
  3. dd()
  4. wszystkie się skompilują

Tylko funkcje wirtualne mogą być oznaczone poprzez override. Funkcja dd() nie jest wirtualna w klasie bazowej, a funkcja bar() nie jest zdefiniowana w klasie bazowej.

 

3. Poniższy kod ma za zadanie policzyć liczbę elementów parzystych w wektorze v. Co należy wstawić na listę przechwytująca funkcji lamba zamiast [XXX], aby ten kod działał zgodnie z założeniami?
int even_count = 0;
std::vector<int > v {1, 3, 4, 3, 6, 3, 7, 6};
std::for_each(v.begin(), v.end(), [XXX](int n) {
    if (n % 2 == 0)
        ++even_count;
});
cout << "There are " << even_count << " even numbers in the vector." << endl;
  1. [&even_count]
  2. [even_count]
  3. [&]
  4. [=]
  5. []
  6. [=, &even_count]

Musimy przechwycić zmienną even_count przez referencję, aby można ją było modyfikować, więc każdy rodzaj listy przechwytującej, na którym even_count będzie przechwycone przez referencję będzie poprawny.

 

4. Jakie słowa kluczowe można wstawić w poniższym kodzie w miejsce oznaczone _______, aby się on kompilował?
struct C {
    C() _______ ;
    C(const C& c);
    void doSth(int a);
    void doSth(double b);
    virtual void doSthElse();
};

struct D : C {
    void doSthElse();
};
  1.  = default
  2.  = delete
  3.  final
  4.  override
  5.  noexcept
  6.  = 0

Konstruktor domyślny może być oznaczony jako = default. Każda funkcja może być oznaczona jako = delete, a więc także konstruktor domyślny. Każdą funkcję można również oznaczyć jako noexcept, jeśli gwarantujemy że nie wyjdzie z niej żaden wyjątek. Oznaczanie kontruktora jako final nie ma żadnego sensu i nie jest poprawne, bo konstruktory nie są dziedziczone. Override podobnie nie zadziała, bo konstruktorów nigdy nie nadpisujemy w klasach pochodnych. Konstruktor nie może być również abstrakcyjny, bo nie może być wirtualny.