Zkouška 13.2.2012

Základní kurs objektově orientovaného programování v C++. Třídy a objekty, zapouzdření, metody, plymorfismus. Abstraktní datové typy, přetěžování. Kontejnery, iterátory, algoritmy. Šablony, generické programování, kompilační polymorfismus. Výjimky. Bezpečné a přenositelné programování, vazby na OS.
mathemage
Matfyz(ák|ačka) level III
Příspěvky: 130
Registrován: 14. 1. 2011 10:03
Typ studia: Informatika Ph.D.
Kontaktovat uživatele:

Zkouška 13.2.2012

Příspěvek od mathemage »

(1)

Kód: Vybrat vše

int a;
int f(int p, int q) {
  a = p + q;
  p = a * q;
  return a+p;
}
 
int g() {
  a = 3;
  return f(a, a);
}

Co vrati fce g?

- 24.

(2) Přepokládejme následující kód:

Kód: Vybrat vše

class T {/* */};
T * x = new T[100];

Jaká je správné dealokace x?

-

Kód: Vybrat vše

delete [] x; 

(3) Otázka na téma tříd PES - SAVEC -ZVIRE (potomci a předci jako v přírodě:)

Asi 4 varianty, 3 z nich byly typu

Kód: Vybrat vše

foo = & new bar
což obecně je obskurnost, páč "new" vrací adresu na nově alokovaný objekt a
"&" vrátí "adresu této adresy" (muselo by se přiřadit do dvojitého pointeru
atp.)

4. varianta byla:

Kód: Vybrat vše

ZVIRE *x = new PES
, je úplně správně (ukazatel
a polymorfismus, tj. žádný slicing z kopírování objektů)

(4) Otázka na virtuální metody třídy a třídy z ní dědící. Většina otázek byla
typu:

Kód: Vybrat vše

T x;
T *p = &x;
Co udělá fce "p->fce()", stačilo se dívat vyloženě jen na tu třídu, protože
ukazatel ukazoval na objekt svého typu, takže žádná záludnost v tom nebyla.

Pak tam byla otázka:

Kód: Vybrat vše

class T {
  virtual int f() {return 1;}
  virtual int g() {return 2;}
  int h() {return f();}
}
 
class U : public T {
  virtual int f() {return 3;}
  virtual int g() {return 4;}
  int h() {return g();}
}
 
U y;
T *p = &y;

Co vrátí "p->h()"?

-3.
Už bylo na socketce, jen stručně: Při kompilaci se určí, který prototyp fce se
zavolá (v závislosti na počtu a typu parametrů, vybere se ta s nejlevnější
konverzí parametrů). Protože je to pointer na třídu T, je to verze "T::h()",
ta bude vyžadovat návratovou hodnotu fce f();
V druhé fázi za běhu se pointer "p" na svoji VMT, to je VMT patřící "U", proto
se volá "U::f()".

(5)

Kód: Vybrat vše

class T {
  virtual int f();
}
 
class U : public T {      
  virtual int f();
}
 
U y;
T x = y;

Jaka fce se zavola pri x.f()?

- T::f(), nepřiřazujeme referenci ani pointerem, takže VMT se nezkopiruje, ale
zůstavá ta stará z "class T".

(6)

Kód: Vybrat vše

class U {
public:
  int a;
 
  U() {a = 1;}
  U(int i) {a = i + 2;}
  U(const U & b) {a = b.a}
};
 
class T : public U {
public:
  T() {}
  T(int i) {a = i + 3;}
  T(const U & b) : U(b.a) {}
};
 
T x = U();

Jakou bude mít na konci "x.a" hodnotu?

- 3. (Nejprve bezparemtricky konstruktor "U()"...a == 1, tento objekt se
zkopiruje do x pres copy-constructor "T(const U & b)", ten zavola "U(int
i)"...a == 3)

(7)

Kód: Vybrat vše

class T {
/* ... */
public:
  virtual ~T();
private:
  T(const T & x);
  T & operator=(const T & x);
};

K čemu se hodí dvě výše uvedené privátní metody:

- ke korektnímu kopírování objektů...tady mělo být NE, ale já měl, ANO (pokud
by "T" definovala nějaké metody, které by je využívaly, obešlo by to tu
skutečnost, že jsou private). Nakonec mi řekl, že by mi i tohle asi uznal, i
když jsem to nepotřeboval, protože jsem z celýho testu měl zakroužkovaný jen
tohle (a na dvojku můžou být "až" 2 zakroužkovaný chyby)
- k zabránění nežádoucímu (ano, skutečně "nežádoucímu", nikoliv
"nežádoucího":) kopírování...ANO (díky tomu, že jsou private, tak ani
potomci to nedokážou)
- k ničemu - deklaraci nelze překompilovat...NE (vše je v cajku)
- k naplnění předepsaného rozhraní (tj. využitelnost ve standardních
knihovnách, do kontejnerů atp.)...NE (opět kvůli tomu private)

(8)

Kód: Vybrat vše

class Complex {
/* ... */
public:
  double Re, Im;
  Complex(double r=0.0, double i=0.0) : Re(r), Im(i) {}
  Complex & operator+=(const Complex & b) {
    Re = Re + b.Re;
    Im = Im + b.Im;
    ?????????
  }
};

Co má být (vhodně) doplněno místo "?????????"_?

- Bylo několik možností, všechny vracely hodnotou nějaký nový objekt Complex s
potřebnými hodnotami, ale jediný správně jest:

Kód: Vybrat vše

return * this;

(aby šly dělat třeba věci typu

Kód: Vybrat vše

Complex a, b;
/* ... */
a += a += b;

9) Označte řádek, kde může dojít k běhové chybě (neberte v úvahu bad_alloc,
tj. nedostatek paměti)

Kód: Vybrat vše

void f(std::vector<int> v) {
[a]  std::vector<int>::iterator it;
[b]  it = find(v.begin(), v.end(), 0);
[c]  it = v.insert(it, -1);
[d]  it = v.insert(it + 2, -2);
}

- Jedině [d], protože "it + 2" může jít mimo rozsah (až za nový "v.end()");
Carpe Diem!
Odpovědět

Zpět na „NPRG041 Programování v C++“