2008

Transkrypt

2008
1. Mamy definicje czterech klas:
class A1 {public: A1() {cout<<"A1";}};
class A2 : private A1 {public: A2() {cout<<"A2";}};
class A3 {public: A3() {cout<<"A3";}};
class A4 : A3, virtual public A2 {public: A4() {cout<<"A4";}};
Co zobaczymy na ekranie w przypadku poniŜszego kawałka programu?
void f() {static A4 p0;}
static A3 p1;
int main(){ A1 p2;
f();
}
a. A1 A2 A3 A3 A1 A4
b. A3 A1 A2 A4 A3 A1
c. ♦ A3 A1 A1 A2 A3 A4
d. A3 A1 A2 A3 A4 A1
2. Jaką wartość będzie miała zmienna a w wyniku poniŜszego przypisania?
int b = 1;
int a = --b ? b : (b = -10) ? 4 : 5;
a. 0
b. -10
c. ♦ 4
d. 5
3. W której linijce zapis jest niepoprawny, jeśli T jest nazwą typu?
T obiekt; // obiekt typu T da się utworzyć
/* 1 */ const T& const ref = obiekt;
/* 2 */ T const& ptr = obiekt;
/* 3 */ T const *ptr = &obiekt ;
/* 4 */ T const * const ptr = &obiekt;
a. ♦ tylko 1
b. 1 oraz 2
c. 1 oraz 4
d. wszystkie są niepoprawne
4. Co zobaczymy na ekranie w wyniku wywołania funkcji f, jak poniŜej?
void f(int*& c) { c=c+2; cout << *c+1 << endl; } // definicja
// gdzieś w programie
int* tab = new int[4];
tab[0] = 4;
tab[1] = 3;
tab[2] = 2;
tab[3] = 1;
f(tab); // to jest interesujące nas wywołanie
a. 1
b. 2
c. ♦ 3
d. 4
5. Spośród poniŜszych zdań na temat modyfikatora static wybierz to, które jest fałszywe:
a. obiekt statyczny jest widoczny tylko w swojej jednostce translacji
b. statyczna stała typu całkowitego, będąca składową klasy, jest inicjalizowana juŜ w ciele klasy
c. ♦ obiekty statyczne umieszczone w róŜnych plikach inicjalizowane są w kolejności włączenia tych plików do
pliku binarnego (biblioteki, programu)
d. static odnosi się do obiektu lub funkcji
6. Posiadając cztery poniŜsze przeciąŜone wersje funkcji fun:
void fun(int& x) { cout<<"fun_int "; }
void fun(float x) { cout<<"fun_float "; }
template <typename T>
void fun(T x) { cout<<"fun_T "; }
template <>
void fun(double& x) { cout<<"fun_double "; }
co zobaczymy na ekranie w wyniku następujących dwóch wywołań:
fun(1.3); fun(1);
a. fun_float fun_int
b. ♦ fun_T fun_T
c. fun_double fun_int
d. fun_float fun_T
7. Wyobraź sobie klasę A dziedziczącą z B i zarówno A jak i B mają bezargumentowe konstruktory. Aby wywołać
konstruktor B z A, uŜyj:
a. ♦ A() : B() { }
b. A() : { B(); }
c. B() : A() { }
d. B() : { A(); }
8. W wyniku wykonania poniŜszego fragmentu kodu, na ekranie zobaczymy:
auto_ptr<int*> a(new int*);
*a = new int(7);
cout << **a-1 << endl;
a. 7
b. nic, bo szablon auto_ptr naleŜy tu uŜyć z argumentem <int>
c. przypadkową wartość, bo tablice dynamicznie kreowane nie są inicjalizowane Ŝadną początkową wartością
d. ♦ 6
9. Mamy poniŜej definicje czterech klas, jedna zawiera błąd i się nie skompiluje. Która?
class A { public:
class B { public:
A(int n=0) { }
B() : b(*this) { }
const static A a;
B& b;
};
};
A const A::a;
class C { public:
class D { public:
C() : c(0) { }
D(int n=0) : d(0) { }
const C* c;
const D d;
};
};
a. klasa A się nie skompiluje
b. klasa B się nie skompiluje
c. klasa C się nie skompiluje
d. ♦ klasa D się nie skompiluje
10. Pewien student przeciąŜył operator<< w postaci funkcji składowej klasy A:
class A {
int x;
public:
A(int n=0) : x(n) {}
ostream& operator<<(ostream& o) { o << x; }
};
Utowrzył w programie dwa obiekty: A a(4), b(5);
Wybierz, która z linijek w programie mu się skompiluje i zadziała:
a. cout << a << b;
b. b << a << cout;
c. a << cout << b;
d. ♦ a << (b << cout);
11. Z poniŜej podanych zestawów wybierz ten, w którym wymieniono tylko operatory, które przy przeciąŜeniu muszą być
funkcjami składowymi:
a. []
()
->
.*
b. ->
=
->*
,
c. ()
=
->
->*
d. ♦ =
[]
->
()
12. Zdefiniowano następujące wielkości:
int i;
int &r = i;
int *rp = &i;
const int n = i;
const int& rn = n;
const int* pn = &n;
const int* const pnc = &n;
Następnie wykonano cztery porównania badające typ zmiennych z pomocą techniki RTTI (rozpoznawania typu podczas
wykonania):
typeid(i)==typeid(r), typeid(n)==typeid(rn),
typeid(pn)==typeid(pnc), typeid(i)==typeid(n)
Ile z tych porównań da wynik prawdziwy (true)?
a. 1
b. 2
c. 3
d. ♦ 4
13. Mamy obiekt typu lista, na przykład list<int> l; Z poniŜszych operacji wybierz tą, która jest prawidłowa:
a. list<int>::iterator it = l.begin()+1;
b. sort( l.begin(), l.end() );
c. ♦ list<int>::const_reverse_iterator it = l.rend();
d. random_shuffle( l.begin(), l.end() );
14. Klasa B dziedziczy publicznie z klasy A. Definiujemy w klasie B operator przypisania
B& operator=(const B& b) i w jego treści na początku chcemy wykorzystać wywołanie operatora przypisania z
klasy bazowej. Wśród poniŜszych odpowiedzi wskaŜ tą, która jest nieprawidłowa:
a. A::operator=(b);
b. A &ref = *this; ref = b;
c. ♦ A *ptr = &b;
d. this->A::operator(b);
15. Wskaźniki do składowych klasy definiuje się zwykle poza ciałem klasy. Pewien student zdefiniował ten wskaźnik
wewnątrz klasy jako pole statyczne, w taki oto sposób:
class A { public:
A() : a(76), b(65) {}
static int A::*ptr;
int a, b;
};
int A::*A::ptr = &A::b; // definicja pola statycznego
Z poniŜszych operacji wskaŜ tą, która jest poprawnym uŜyciem (wyłuskaniem) wskaźnika ptr i wypisze na ekranie
wartość przechowywaną w zmiennej b (tzn. 65), jeśli w programie najpierw utworzymy wskaźnik do obiektu typu A: A
*ptrA = new A;
a. ♦ cout << ptrA->*ptrA->ptr;
b. cout << ptrA->(*ptr);
c. cout << *(ptrA->ptr);
d. cout << (*ptrA).ptr;
16. Klasa A ma zdefiniowane takie pola:
int& a; int* b; const int c; int const *d; static int e;
przy czym składowa statyczna jest oczywiście zdefiniowana poza ciałem int A::e;
WskaŜ z poniŜszych niepoprawny konstruktor:
a. A() : a(e), c(e) {}
b. A() : d(0), c(7), b(0), a(e) {}
c. A() : a(e), c(0), d(&e) {}
d. ♦ A() : a(0), c(0) {}
17. Spośród poniŜszych słów wskaŜ to, które nie jest słowem kluczowym języka C++
a. explicit
b. goto
c. ♦ exception
d. union
18. Gdzieś w programie widzisz taką linijkę: A::fun(); Wybierz z poniŜszych komentarzy opisujących potencjalne
moŜliwości, jeden niepoprawny.
a. fun() jest statyczną funkcją składową klasy A
b. fun jest statycznym obiektem typu A zdeklarowanym wewnątrz klasy A, potem zdefiniowanym, ponadto klasa ta
ma odpowiedni przeciąŜony operator()
c. fun() jest funkcją zamkniętą w przestrzeni nazw A
d. ♦ fun jest globalnym statycznym obiektem typu A i w klasie tej jest przeciąŜony operator()
19. Wśród poniŜszych stwierdzeń wskaŜ fałszywe:
a. ♦ funkcja unexpected jest wołana gdy wyjątek zgłosi konstruktor obiektu globalnego
b. funkcja terminate domyślnie wywołuje funkcję abort
c. funkcja unexpected domyślnie woła funkcję terminate
d. błąd alokowania pamięci domyślnie sygnalizowany jest wyjątkiem bad_alloc
20. Która funkcja z poniŜszych deklaracji gwarantuje, Ŝe nie zgłosi Ŝadnego wyjątku? (jeśli trzeba, funkcja moŜe być składową
jakiejś klasy):
a. void fun(const exception& e);
b. void fun() const throw(bad_exception);
c. ♦ void fun(void*) throw();
d. void fun(double&) throw(double);
21. Mamy takie oto cztery definicje (wszystkie puste):
enum Krakowiak {}; union Wolowina {};
struct Pershing {}; class Rzeznik {};
Wykorzystano je do zgłoszenia i przechwycenia wyjątku:
try { throw Krakowiak(); } catch (Krakowiak&) {cout<<"Krakowiak";}
try { throw Wolowina(); } catch (Wolowina&) {cout<<"Wolowina";}
try { throw Pershing(); } catch (Pershing&) {cout<<"Pershing";}
try { throw Rzeznik(); } catch (Rzeznik&) {cout<<"Rzeznik";}
WskaŜ, która z poniŜszych odpowiedzi jest poprawna:
a. ♦ wszystkie przypadki są poprawne i działają
b. unia Wolowina nie moŜe być uŜyta jako typ wyjątku
c. pusty typ wyliczeniowy Krakowiak nie moŜe być uŜyty jako typ wyjątku
d. klasa Rzeznik nie moŜe być uŜyta, bo nie ma zdeklarowanych publicznych konstruktora i destruktora,
niezbędnych przy tworzeniu obiektu wyjątku
22. Deklaracje funckji wraz z wartościami domyślnymi parametrów mogą się powtarzać, ale pod pewnymi warunkami. Które z
poniŜszych jest błędne?
a. void fun(int a, int b, int c=3);
void fun(int a, int b, int);
b. void fun(int a, int b, int c=3);
void fun(int a, int b=2, int c);
c. void fun(int a, int b, int c=3);
void fun(int=1, int b=2, int c);
d. ♦ void fun(int a=1, int b, int=3);
void fun(int a, int b=2, int c);
23. Który z poniŜszych kawałków kodu jest niepoprawny:
a. class A { int n;
friend void fun(A &a) { cout << a.n; }
};
b. ♦ class A { int n;
friend void fun() { cout << n; }
};
c. class A { int n;
friend void fun(A &a);
};
void fun(A &a) { cout << a.n; }
d. class A { int n;
friend void fun(A*);
};
void fun(A *a) { cout << (*a).n; }
24. WskaŜ wśród poniŜszych rad na temat dobrego projektowania obiektowego tą, która nie jest właściwa:
a. preferuj kompozycję, a nie dziedziczenie
b. dziedzicz interfejsy, a nie implementacje
c. ♦ jeśli moŜesz, pisz interfejs w oparciu o funkcje wirtualne
d. zidentyfikuj co się moŜe zmieniać i ukryj to
25. Co zobaczymy na ekranie (zakładamy uprzednie włączenie wszystkich potrzebnych plików nagłówkowych)?
int T[] = {-3, -1, 0, 1, 3};
vector<int> vi(T, T+sizeof(T)/sizeof(int));
vector<int>::iterator vit;
ostream_iterator<int> out(cout, " ");
vit = remove_if(vi.begin(), vi.end(), not1(bind1st(less<int>(),0)));
copy(vi.begin(), vit, out);
a. 0 1 3
b. ♦ 1 3
c. -3 -1 0
d. -3 -1
26. Dla poniŜszej definicji szablonu funkcji wskaŜ niepoprawne jej wywołanie:
template <typename A1, typename A2, typename A3>
A1 const& min(A2 const& l, A3 const& r) { return l < r ? l : r; }
a. min<double>(2.2, 1.1);
b. ♦ min<double, int, double>(22, 3.14);
c. min<bool, bool>(1, false);
d. int *p1, *p2; min<int*>(p1, p2);
27. Jeśli mapę wypełnimy jak poniŜej, to co zobaczymy na ekranie?
map<string, int> msi;
msi["kota"];
msi.insert(pair<string,int>("ala",2));
msi["ma"]++;
map<string, int>::iterator itm = msi.begin();
for( ; itm != msi.end(); ++itm)
cout << itm->first << " " << itm->second << " ";
a. ala 2 kota 1 ma 2
b. ala 2 ma 1 kota 0
c. ♦ ala 2 kota 0 ma 1
d. kota 0 ma 1 ala 2
28. Spośród poniŜszych wskaŜ poprawny predykat:
a. class A { public: void operator()(bool p); };
b. struct A { int operator(int a)(); };
c. ♦ class A { public: bool operator()(double, int); };
d. struct A { double operator()(); };
29. JeŜeli vector<const char*> v; wypełnimy trzema słowami: "ala", "ma", "kota", oraz zdefiniujemy iterator
ostream_iterator<const char*> out(cout, " "); to na ekranie w efekcie poniŜszej linii zobaczymy
remove_copy_if(v.begin(),v.end(),out,bind1st(ptr_fun(strcmp),"ma"));
a. ala
b. ala kota
c. ala ma
d. ♦ ma
30. Wybierz prawidłowy opis wzorca dekoratora:
a. ♦ pozwala na dynamiczne dodanie dodatkowych odpowiedzialności do obieku
b. definiuje rodzinę algorytmów, kapsułkuje kaŜdy z nich i czyni wymiennymi
c. definiuje interfejs do tworzenia obiektu, ale zleca jego tworzenie podklasom
d. słuŜy dokonaniu rozdziału pomiędzy abstrakcją a jej implementacją
31. Jaka liczba zostanie wyświetlona w efekcie działania poniŜszego kawałka kodu:
char T[] = {1,2,3,4,5,6,7,8};
cout << *(reinterpret_cast<short*>(T) + 2) << endl;
a. ♦ 1541
b. 3
c. 1027
d. 1286
32. Co zobaczymy na ekranie w efekcie działania poniŜszego kawałka kodu:
class A {
int n;
static int i;
public:
A() : n(++i) {}
int fun() { return n; }
};
int A::i = 0;
int main() {
int (A::*p)() = &A::fun;
A* ptr = new A[3];
cout << (*((++ptr)++).*p)() << endl;
}
a. kod się nie skompiluje, bo w ostatniej linii jest błąd
b. 1
c. ♦ 2
d. 3
33. Pewien student przeciąŜył w klasie A operator postinkrementacji i postanowił uŜyć swoje dzieło w nietypowy sposób.
Oceń jaki będzie tego efekt:
class A { public:
A() : x(0) {} // konstruktor
A operator++(int) { A temp; ++x; return temp; } // przeciąŜony
int x;
};
// gdzieś w programie
A obiekt1;
obiekt1++++++;
cout << obiekt1.x << endl;
a. to jest niepoprawne składniowo i się nie skompiluje
b. na ekranie zobaczymy liczbę 3
c. ♦ na ekranie zobaczymy liczbę 1
d. na ekranie zobaczymy liczbę 0
34. Mamy pewien typ TYP (jest to jakiś wskaźnik), zdefiniowany poprzez typedef:
typedef int (*(*const(*TYP)())[2])();
Utworzony i poprawnie przypisany zostaje: TYP obiekt. Wybierz z poniŜszych poprawne wywołanie, zgodne ze
specyfikacją powyŜszego typu.
a. ♦ (*(*obiekt)())[1]();
b. (*(*obiekt)())()[1];
c. *((*obiekt)())[1]();
d. ((*obiekt)(*)())[1]();
35. Przyjrzyj się poniŜszym przykładom tworzenia i inicjalizacji obiektów wraz z komentarzem i wskaŜ tą odpowiedź, która
jest niepoprawna:
a. ♦ int x = 12; { int x = x; }
// lokalna zmienna x zostanie zainicjalizowana wartością 12
b. const int i = 2; { int i[i]; }
// zostanie utworzona lokalna dwuelementowa tablica int
c. const int x = 12; { enum { x = x; }; }
// element typu wyliczeniowego inicjalizowany jest wartością 12
d. struct X { enum E {z=16}; int b[X::z]; };
// poprawne, bo do nazwy składnika klasy moŜna odwołać się od razu po jego wystąpieniu