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
"&" 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
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;
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()");