ОО1/Питалице
На овој страници скупљени су разни испитни примери који су се можда појавили на испиту али им се не зна рок појављивања или једноставно није било довољно добро формулисаних питалица из тог рока како би се одвојили у страницу рока.
- За питања са више одговора, тачни одговори су подебљани и уоквирени
- За питања за које се одговори уносе, тачни одговори су подвучени и сакривени, тако да се прикажу када изаберете тај текст (пример: овако)
- Притисните лево дугме испод за сакривање и откривање свих одговора, или десно дугме за укључивање и искључивање интерактивног режима:
1. задатак
Шта је од наведеног тачно:
- Објекат јавно изведене класе наслеђује само имплементацију основне класе, а не и уговор
- Објекат заштићене изведене класе је једна врста објекта основне класе у свакој глобалној функцији
- Код приватног извођења наслеђује се уговор основне класе
- Јавним извођењем само се успоставља релација садржаја између објекта изведене класе и наслеђеног подобјекта основне класе
- Ништа од понуђеног
2. задатак
Шта исписује следећи код:
#include <iostream>
using namespace std;
template <typename T> class Klasa {
public:
template <typename U> void m (U u) { cout << "1"; }
void m (int u) {cout << "2"; }
};
template <typename T> class Klasa <T*> {
public:
template <typename U> void m (U u) { cout << "3"; }
void m (int u) {cout << "4"; }
};
int main () {
Klasa <int*>().m<float>(9);
Klasa <int> ().m(9);
Klasa <int> ().m('a');
Klasa <int*>().m<int>(2);
}
Одговор: 3213
Објашњење: Прва метода ради над класом параметризованом са int*, па се бира специјализација, а метода је параметризована са float (уместо int, али требало би да је чињеница да је експлицитно параметризована довољна) па се бира шаблонска метода. Друга метода ради над класом параметризованом са int, па се бира основни шаблон, и позива нешаблонска метода јер параметар типа int тачно одговара параметрима методе без конверзије. Трећа метода је слично као друга, али не одговара параметрима нешаблонске методе без конверзије, па се позива шаблонска. Четврта метода је као прва.
3. задатак
Шта исписује следећи код:
#include <iostream>
using namespace std;
class Klasa {};
int main () {
try {
try {
cout << "0";
throw Klasa();
cout << "1";
}
catch (...) { cout << "2"; }
cout << "3";
}
catch (Klasa i) {cout << "4"; }
cout << "5";
return 0;
}
Одговор: 0235
Објашњење: Прво се исписује 0. 1 се не исписује јер је пре тога бачен изузетак. Изузетак се хвата у catch грани за све руковаоце и исписује 2, па се наставља регуларним роком и исписују 3 и 5.
4. задатак
Шта важи за апстрактне класе?
- не могу се правити објекти апстрактне класе зато што она не може имати деструктор
- наткласа апстрактне класе је обавезно апстрактна класа
- класа изведена из апстрактне класе мора да редефинише све наслеђене апстрактне методе
- не могу се стварати објекти апстрактне класе већ само показивачи и рефенце на њу, који могу показивати (упућивати) на објекте конкретних изведених класа које нису апстрактне
5. задатак
Шта исписује следећи код:
#include <iostream>
using namespace std;
void f() noexcept {}
void g() noexcept (!noexcept (f())) {}
void h() noexcept (noexcept (g())) {}
void m() noexcept (noexcept (f()) || noexcept (g())) {}
int main () {
cout << (noexcept (f()) ? 1:0);
cout << (noexcept (g()) ? 1:0);
cout << (noexcept (h()) ? 1:0);
cout << (noexcept (m()) ? 1:0);
return 0;
}
Одговор: 1001
Објашњење: Функција f је noexcept. Функција g је обрнуто од noexcept за f, тако да није noexcept. Функција h је исто noexcept колико и g, тако да није noexcept. Функција m је noexcept уколико су f или g noexcept, тако да је noexcept.
6. задатак
Шта исписује дати програм:
#include <iostream>
using namespace std;
class A {
public:
static int i;
A() { i++; }
};
int A::i = 0;
class B : virtual public A {
public:
B() { i++; }
};
class C : public A {
public:
C() { i++; }
};
class D : public B, public C {
public:
void pisi() { cout << i; }
};
int main () {
D d;
d.pisi();
return 0;
}
Одговор: 4
Објашњење: Због тога што C није виртуелно изведена из A, A ће бити наслеђена два пута и два пута ће се позвати конструктор за подобјекат те класе. Поред тога се позивају конструктори за B и C, и на крају се тај број исписује у конструктору D.
7. задатак
Шта исписује следећи код:
#include <iostream>
using namespace std;
class A {
public:
virtual void m() {}
};
class B : public A {};
class C : public B {};
int main () {
A *pa = new B();
B *pb = new C();
B *b = dynamic_cast <B*>(pa);
C *c = dynamic_cast <C*> (pa);
C *d = dynamic_cast <C*> (pb);
if (b == nullptr) cout << 'b';
if (c == nullptr) cout << 'c';
if (d == nullptr) cout << 'd';
return 0;
}
- баца се изузетак бад_цаст
- д
- цд
- ц
- бцд
Објашњење: Слова се исписују када није могуће урадити неки каст. Овде једино није могуће урадити кастовање pa у показивач на C, јер је pa показивач на објекат класе B и не може се понашати као класа C.
8. задатак
Шта исписује следећи код:
#include <iostream>
using namespace std;
class A {
public:
A(int i) {
if (i < 5) cout << 'a';
else throw 'b';
}
};
int main() {
int i = 1;
if (noexcept(A(i++))) cout << i;
else cout << 2*i;
return 0;
}
Одговор: 2
Објашњење: Конструктор класа A може да баци изузетак и због тога није noexcept. Израз noexcept се евалуира у време превођења а не извршавања, и због тога се i не повећава при провери да ли је конструктор класе A noexcept. Пошто није, исписује се двострука вредност i које није повећано за 1, а то је 2.
9. задатак
(Октобар 2020, 9. задатак) Заокружити исправне изразе, ако је дат следећи код:
template <typename T=int, int k=10>
class Niz { T niz[k]; };
Низ<инт*, 20> н1;Низ<инт*&, 20> н2;Низ<20> н3;Низ<> н4;Низ<доубле, 5.5> н5;Низ н6;
Објашњење: Одговор под ф) се преводи само од C++17 и новијих стандарда. Унутар класе се прави низ података, а у одговору под б) се прослеђује тип референце, што је немогуће. У одговору под ц) први аргумент је константа а не тип, а у одговору под е) се уместо int константе прослеђује double.
10. задатак
Шта исписује следећи код:
#include <iostream>
using namespace std;
class O {};
class I: public O {};
int main() {
try {
throw I();
cout << "1";
}
catch(O o) {
cout << "5";
try {
throw I();
cout << "3";
}
catch(I i) { cout << "2"; }
}
catch(I i) { cout << "4"; }
cout << "8";
return 0;
}
Одговор: 528
Објашњење: Руковаоци изузетака се гледају редом којим пишу у коду, па се прво наилази на руковалац типа O и у њему се хвата изузетак (пошто тип изведене класе одговара руковаоцу основне). У руковаоцу се баца и одмах после хвата изузетак типа изведене класе, па се исписује 2. На крају се програм завршава регуларно и исписује још 8.
11. задатак
Шта исписује следећи програм (уписати -1 уколико се програм не преводи):
#include <iostream>
using namespace std;
class A {
public:
virtual void m1() = 0;
virtual void m2() = 0;
};
class B : public A {
public:
void m1() { cout << "1"; }
};
class C : public A {
public:
void m2() { cout << "2"; }
};
class D : public B, public C {
public:
void m2() { cout << "3"; }
};
int main() {
D d;
d.m2();
return 0;
}
Одговор: -1
Објашњење: Не преводи се, због тога што је D апстрактна класа. Методе m1 и m2 се надјачавају у класама B и C, али пошто нису виртуелно изведене постоје два подобјекта класе A и један пар метода који није надјачан уопште. У класи D се надјачава метод m2, али метод m1 преко класе C још увек није надјачан, па је D и даље апстрактна класа.
12. задатак
(Јул 2020, 10. задатак) Шта важи за основну и изведену класу, ако обе имају празна тела, а извођење је јавно:
- Изведена класа наслеђује конструктор
- Изведена класа не наслеђује деструктор
- Изведена класа има подразумевани конструктор са празним телом
- Изведена класа има деструктор који има празно тело
- Изведена класа има аутоматски генерисан копирајући конструктор
13. задатак
Шта исписује следећи програм:
#include <iostream>
using namespace std;
class X {
public:
X() {}
void m(int i) {
try {
if (i == 2) throw 2;
cout << "1" << endl;
}
catch (double k) { cout << "2" << endl; }
}
};
int main() {
X x;
try {
x.m(2);
}
catch (int k) { cout << "3" << endl; }
return 0;
}
Одговор: 3
Објашњење: Улази се у методу и пошто је аргумент 2 баца се аргумент типа int и не хвата у руковаоцу унутар методе типа double, већ оном ван методе.
14. задатак
Колико ће се звездица исписати?
#include <iostream>
using namespace std;
void f(int i, int& j) { i++; j++; }
int main(){
for (int i = 0, j = 0; i < 3 && j < 4; f(i, j))
cout << '*';
return 0;
}
Одговор: 4
Објашњење: Функција f повећава свој локални аргумент i, али пошто није прослеђен по референци он се не инкреметира ван петље, па је ефективан услов j < 4.
15. задатак
Шта исписује следећи програм:
#include <iostream>
using namespace std;
class A {
int x, y;
public:
A(int xx, int yy) : x(xx) , y(yy){}
double div() { if (y == 0) throw x; return x/y; }
int mod() { if (y == 0) throw 0; return x % y; }
};
int main() {
A a(4, 0), aa(3, 5);
try { cout << a.div(); } catch(int x) { cout << x; }
try { cout << a.mod(); } catch(int x) { cout << x; }
try { cout << aa.div(); } catch(int x) { cout << x; }
try { cout << aa.mod(); } catch(int x) { cout << x; }
return 0;
}
Одговор: 4003
Објашњење: Прва два позива div и mod ће бацати грешке вредности x (4) и 0 респективно, па ће се те грешке исписати. Друга два позива ће исписати вредности те две операције, односно 0 и 3.
16. задатак
Заокружи тачна тврђења:
- Генеричке функције убрзавају извршавање програма
- Генеричке функције убрзавају превођење
- Генеричке функције и класе омогућавају бољу реупотребу кода
- Генерички механизам омогућава генерисање функција са различитим типовима параметара у току извршавања програма
17. задатак
Заокружи тачна тврђења:
template <typename T>
void swap (T *a, T *b){
T c;
for (int i = 0; i < n; i++) {
c = a[i];
a[i] = b[i];
b[i] = c;
}
}
За класу Т мора да постоји:
- Подразумевани конструктор
- Оператор доделе вредности
- Оператор []
- Копирајући конструктор
- Метода која врши полиморфну копију
Објашњење: Подразумеваним конструктором се ствара објекат c. Оператором доделе вредности се том објекту додељује други објекат из низа a. Оператор [] није потребан јер се овде индексирају низови, а не позива тај оператор над самим објектом.
18. задатак
(Септембар 2020, 6. задатак) Ако је еxцептион класа изузетака и из ње је изведена класа I, а из класе I даље изведена класа II, којим редоследом треба навести руковаоце изузецима (заокружити једно или више):
- еxцептион, I , II , ...
- II, I, еxцептион, ...
- I, II , еxцептион, ...
- II, I, ..., еxцептион
- ..., еxцептион, I, II
19. задатак
Шта исписује следећи програм:
#include <iostream>
using namespace std;
template<class T, class U, int I> struct X {
void f() { cout << "Osnovni sablon" << endl; }
};
template<class T, int I> struct X<T, T*, I> {
void f() { cout << "Specijalizacija 1" << endl; }
};
template<class T> struct X<int, T*, 10> {
void f() { cout << "Specijalizacija 2" << endl; }
};
int main() {
X<int, int*, 10> f;
f.f();
return 0;
}
- Специјализација 1
- Специјализација 2
- Грешка јер се приступа приватном пољу
- Грешка због двозначности шаблона
Објашњење: Ово питање може бити јако збуњујуће јер је на презентацији професора Игора Тартаље погрешно наведено да се бира специјализација "са мање параметара". Заправо, једна специјализација је специјализованија од друге када покрива подскуп комбинација типова и константи које покрива прва. На пример, специјализованији случај прве специјизације би био <T, T*, 10> или <int, int*, I> јер све могуће комбинације типова које одговарају једној од ове две специјализације одговарају и првој специјализацији. Ипак, у овом задатку то није случај. Комбинација <int, char*, 10> одговара само другој, а <int, int*, 11> само првој специјализацији. Због овога ниједна од њих није специјализованији случај и разрешење шаблона је немогуће учинити због двозначности. Професору је за ову грешку речено у јануару 2021. године.
20. задатак
Шта исписује следећи програм:
#include <iostream>
using namespace std;
void fun(int p) {
try {
throw p;
}
catch (int p) { cout << ++p; throw; }
}
int main() {
int p = 1;
try {
try {
fun(p);
cout << ++p;
}
catch (int p) { cout << ++p; }
cout << ++p;
}
catch (int p) { cout << ++p; }
return 0;
}
Одговор: 222
Објашњење: Из функције се баца изузетак и у њој се хвата. Пошто се хвата по вредности, инкрементирање ће се десити само над локалним објектом, а сами објекат изузетка се неће мењати. Затим се исти изузетак као раније (неизмењени) баца из функције, и хвата у првом следећем руковаоцу. Ту се објекат изузетка који се опет хвата по вредности зове исто као и променљива која је оригинално била прослеђена функцији, па ће се инкрементирање и испис десити над објектом изузетка. После тога, инкрементирање и испис се дешава над оригиналном променљивом.
21. задатак
Шта исписује следећи програм:
#include <iostream>
using namespace std;
int main() {
int x = 10;
double y = 1.5;
decltype(++x - y) a = y-- + 5;
cout << x << ' ' << y << ' ' << a;
return 0;
}
Одговор: 10 0.5 6.5
Објашњење: decltype се израчунава при превођењу па се вредност x не мења. Пошто је тип у који могу да стану и int и double заправо double, вредност a ће бити за 5 већа од y, а у том процесу се y смањује за 1.
22. задатак
Шта исписује следећи програм:
#include <iostream>
using namespace std;
class Klasa {};
class Izvedena : public Klasa {};
int main() {
try {
throw Izvedena();
}
catch (Izvedena * i) { cout << "3"; }
catch (Klasa i) { cout << "4"; }
catch (Izvedena i) { cout << "5"; }
return 0;
}
Одговор: 4
Објашњење: Руковалац типа показивача не може хватати изузетак који није типа показивача. Пошто се руковаоци гледају редом, следећи на листи руковалаца ће бити Klasa i, који одговара јер је Izvedena изведена из Klasa, па се исписује 4.
23. задатак
Шта је проблем код дефиниције функције:
class X {
public:
X operator+(const X& x) const;
};
- Исправна је
- Није исправна јер за бинарни оператор + фали још један аргумент
- Није исправна јер нису обезбеђене бочне вредности
- Није исправна јер ова функција МОРА да враћа референцу на лвредност
24. задатак
Шта од следећег важи за деструкторе:
- Деструктор нема аргументе
- Деструктор може имати један аргумент ако има подразумевану вредност
- Деструктор враћа воид
- Деструктор се може експлицитно позвати
25. задатак
Шта исписује следећи програм:
#include <iostream>
using namespace std;
class A {
int i;
public:
A(int ii) : i(ii) { cout << i; }
};
class B {
A a1, a2;
public:
B(A a11=A(5), A a22=A(6)) : a1(a11), a2(a22) {}
};
int main() {
int i = 7;
A a(i);
B b(a);
return 0;
}
Одговор: 76
Објашњење: Конструктор се прво позива при прављењу објекта a. При прослеђивању тог објекта конструктору класе B позива се копирајући конструктор који не исписује ништа, а за други аргумент се конструише објекат класе A са аргументом 6 као подразумевани аргумент.
26. задатак
Шта исписује следећи код:
#include <iostream>
using namespace std;
class X {
public:
X(int a, int b=0) {
cout << "1";
}
X() { cout << "2"; }
X(double d) { cout << "3"; }
X(const X &X) { cout << "4"; }
};
int main() {
X X1, X2(1), X3(X1), X4(.5);
return 0;
}
Одговор: 2143
27. задатак
Шта је проблем код дефинисања оператора +?
class Klasa {
public:
Klasa operator+(const Klasa& k1, const Klasa& k2);
};
- Нема проблема.
- Неправилна промена права приступа.
- Промена н-арности оператора.
- Прослеђивање аргумената оператора по референци.
- Ништа од понуђеног.
Објашњење: Ова нестатичка метода има аргумент this и два аргумента класног типа, чинећи је тринарним оператором.
28. задатак
Која наредба је еквивалентна b-- у коду?
int a = 5;
int& b = a;
int* c = &a;
- ниједна
c--а--(*ц)--c = a-1
29. задатак
Како се правилно дефинише низ од n целих бројева, ако n задаје корисник током извршавања?
инт низ = неw инт[н];инт *низ = неw инт[н];инт низ = неw инт*[н];инт низ[н];инт *низ[н];
30. задатак
Шта исписује следећи код:
class K {
public:
K(int k) { cout << k; }
};
class A {
K k2 = 1, k1 = 2;
public:
A(int i, int j) : k1(i), k2(j) {}
};
int main() {
A a(3, 4);
return 0;
}
Одговор: 43
Објашњење: Овде је фора да је редослед конструкције по редоследу навођења у класи а не у иницијализаторској листи.
31. задатак
Шта исписује следећи код:
#include <iostream>
using namespace std;
class A {
int a;
public:
A() { a = 1; cout << "A"; }
};
class B {
A a;
public:
B() { cout << "B"; }
};
class C {
B b;
A a;
public:
C() { cout << "C"; }
};
int main() {
C c;
return 0;
}
Одговор: АБАЦ
Објашњење: Креће иницијализација C. Прво се иницијализује њено поље типа Б, али се одмах прелази на иницијализацију поља типа А од класе типа Б, па се исписује А а затим Б. Иницијализује се још једно боље типа А класе C и на крају се завршава иницијализација C.
32. задатак
(Јул 2020, 7. задатак) Да ли су следећи механизми статички или динамички?
- Генерици - статички
- Преклапање оператора - статички
- Полиморфизам - динамички
- Преклапање имена функција - статички
- Обрада изузетака - динамички
33. задатак
Које особине су заједничке за операторе () и ->:
- преклапају се као бинарни
- могу се преклопити као глобална пријатељска функција
- тип резултата мора бити једнак типу операнда
- преклапањем није могуће променити приоритет оператора
- резултат мора бити показивачког типа
34. задатак
class T {
public:
void m(int x) const;
};
Ког је типа this у методу m?
T*const T*const T&цонст Т* цонстT* const
Објашњење: this је обично T* const (константни показивач). Са модификатором const методе, оно постаје const T* const (константни показивач на константу).
35. задатак
Шта исписује следећи код:
#include <iostream>
using namespace std;
class A {
private:
int i;
public:
A(int ii) { i = ii; }
int dohvati() { return i; }
int operator()() { return 3; }
};
static int a() { return 4; }
int main() {
A a(2);
cout << a();
return 0;
}
Одговор: 3
36. задатак
Коју вредност ће имати reg_br?
class A {
static int reg_br;
int id = reg_br++;
int i;
public:
A(int ii) { i = ii; reg_br = 5; }
};
int A::reg_br = 2;
int main() {
A a(2);
return 0;
}
Одговор: 5
Објашњење: Конструктор се позива након иницијализатора поља, па ће reg_br прво бити инкрементирано за 1 а затим постављено на 5.
37. задатак
Које тврдње за статички каст су тачне?
- Користи се за уклањање/додавање модификатора
constнеком типу - Користи се за конверзије између нумеричких типова
- Користи се за корисничке конверзије
- Користи се за конверзије типова података који нису у логичкој вези
- Користи се за конверзије између показивачких типова
- Користи се за преносиве конверзије
- Користи се за непреносиве конверзије
38. задатак
Конструктор неке класе се извршава:
- Када се извршава дефиниција статичког објекта неке класе
- Када се врши додела вредности објекту дате класе
- Када се конструктор експлицитно позове и створи се привремени објекат дате класе
- Када се ствара динамички објекат дате класе
- Када се врши пренос аргумента у параметар дате класе по вредности
- Када се из функције враћа резултат типа дате класе по вредности
39. задатак
Које тврдње су исправне:
- Досег глобалне променљиве је од дефиниције до краја фајла у којем је дефинисана
- Досег класног атрибута је од места где је наведен до краја дефиниције класе
- Досег променљиве дефинисане у дефиниције фор петље, према стандарду, је до краја окружујућег блока фор петље
- Досег локалне променљиве је од почетка до краја блока у којем је дефинисана
- Досег лабеле је од места где је дефинисана до краја тела функције
40. задатак
Упућивач (референца) на двредност је двредност:
- Тачно
- Нетачно
41. задатак
Које тврдње су исправне:
- Објекат класе мора испољавати полиморфно понашање
- Објекат класе је опис корисничког структуираног типа
- Објекат класе је нешто (у меморији) што има стање, понашање и идентитет
- Објекат класе је опис понашање сродних примерака неке апстракције
- Објекат у ширем смислу је податак одређеног типа који у време извршавања програма има одређено место у меморији
42. задатак
(Јул 2020, 1. задатак) Шта се у ком кораку историјата објекте парадигме десило:
| Апстракција | Програмски језик |
|---|---|
|
|
Објашњење: Ови задаци се обично не појављују у прва два рока.
43. задатак
(Јул 2020, 3. задатак) Како се из главне функције може приступити tmp?
namespace A {
namespace B {
int tmp = 2;
}
}
Одговор: А::Б::тмп
44. задатак
(Септембар 2020, 1. задатак) Шта исписује следећи програм:
#include <iostream>
using namespace std;
class X {
public:
X() { cout << 'X'; }
X(char c) { cout << 'X' << c; }
};
class A : virtual X {
public:
A() : X('a') { cout << 'A'; }
};
class B : X {
public:
B() : X('b') { cout << 'B'; }
};
class C : virtual X {
public:
C() : X('c') { cout << 'C'; }
};
class Y : A, virtual B, C {
public:
Y() { cout << 'Y'; }
};
int main() {
Y y;
return 0;
}
Одговор: XXбБАЦY
Објашњење:
- Раде се два обиласка, први где обилазимо све класе у стаблу наслеђивања по дубини на основу редоследа наведеног у дефиницији класе и иницијализујемо виртуелне, а други где обилазимо опет по дубини и иницијализујемо остале.
- Креће се са иницијализацијом Y. Y је прво невиртуелно изведена из А, па се обилази А без иницијализације.
- А је виртуелно изведена из X, па се иницијализује X.
- Када се класа иницијализује због виртуелног наслеђивања, који конструктор ће се позвати одређује најплића класа, у овом случају Y (ово не пише на предавањима). Пошто није одређено који се конструктор позива у Y, позива се подразумевани конструктор и исписује се X.
- Обилазак А је завршен и прелази се на Б, која је виртуелно изведена па се зато иницијализује.
- Б је невиртуелно изведена из X, па се X поново иницијализује (јер је раније била иницијализована виртуелно), овог пута позивајући конструктор који дефинише Б, па се исписује Xб.
- Иницијализација Б је завршена и исписује се Б. Прелази се на C, које је виртуелно изведено из X, али пошто је X већ иницијализована виртуелно овде се не дешава иницијализација.
- А је виртуелно изведена из X, па се иницијализује X.
- Прелази се на другу фазу. Иницијализује се А.
- Подобјекат X класе А је већ иницијализован, па се само исписује А и прелази на иницијализацију Б.
- Б је већ иницијализовано, прелази се на иницијализацију C.
- Подобјекат X класе C је већ иницијализован, па се само исписује C.
- На крају иницијализације се исписује Y.
45. задатак
(Септембар 2020, 4. задатак) Стварни аргумент шаблона може бити:
- Име шаблонске класе
- Име праве класе
- Функција
- Шаблонска класа с параметрима
- Параметар
46. задатак
(Колоквијум ИР 2021)Шта исписује следећи сегмент кода написан на програмском језику C++:
enum E {a=2, b, c, d, e, f=3, g, h=3};
cout << E::b << E::f << E::h;
Одговор: 333
Објашњење: Поља енумерације се нумеришу редом бројевима за један већим од претходног почевши од првог којем је експлицитно задата вредност или од 0.