asd Flashcards
int returnByValue() { return 5; }
int& returnByReference() { static int x{ 5 }; return x; }
int main() { int value{ returnByReference() }; int &ref{ returnByValue() }; const int &cref{ returnByValue() };
return 0; }
-static ensures x isn’t destroyed when the function ends
case A – ok, treated as return by value
case B – compile error since the value is an r-value, and an r-value can’t bind to a non-const reference
case C – ok, the lifetime of the return value is extended to the lifetime of cref
const int& returnByReference()
{
return 5;
}
int main() { const int &ref { returnByReference() }; }
runtime error
const int returnByValue()
{
return 5;
}
int main() { const int &ref { returnByValue() }; }
ok, we’re extending the lifetime of the copy passed back to main
string get_name() { string s="magic"; return s; } int main() { string p=get_name(); std::cout<<p></p>
ok
#include using namespace std; string get_name() { string s="magic"; return s; } int main() { string& p=get_name(); std::cout<<p></p>
//nu compileaza //nu ai voie sa faci bind unei referinte de o valoare temporara
#include using namespace std; const string& get_name() { string s="magic"; return s; } int main() { string& p=get_name(); std::cout<<p></p>
nu compileaza, s-a scapat ilegal de const
#include using namespace std; string get_name() { string s="magic"; return s; } int main() { const string& p=get_name(); std::cout<<p></p>
/functioneaza, iar valoarea temporara va fi distrusa atunci cand va iesi referinta din scop
#include using namespace std; const string& get_name() { string s="magic"; return s; } int main() { const string& p=get_name(); std::cout
runtime error, se mosteneste durata de viata a valorii trimise prin const reference si era o variabila locala deci a murit
#include using namespace std; string o= "opapa"; const string& get_name() { string s="magic"; return o; } int main() { const string& p=get_name(); std::cout<
opapa
Ce e aia lifetime extension? cand functioneaza si cand nu functioneaza?
Functioneaza atunci cand un local const T& sau T&& este initializat din reziltatul unei expresii care returneaza:
-un temporar T
-T subobiectul unui temporar(un struct care contine T)
In cazul acesta, obiectul T este distrus atucni cand referinta iese din scop.
Cand nu merge lifetime extension?
-cand facem assignment la T& nu const T& - eroare de compilare
-cand se face non-polimorfic type conversion. type-conversion e permisa atunci cand faci assignment la T& dintr-un temporar U , unde U este copil al lui T
Compileaza sau nu? Daca da de ce, daca nu de ce? #include using namespace std; struct Person { struct Name { std::string first_name; std::string last_name; } name; }; Person birth; int main() { const std::string &first_name = birth.name.first_name; }
Merge, si birth este distrus dupa ultima acolada.
Spuneţi de câte ori se execută fiecare constructor în programul de mai jos şi în ce ordine. #include class cls1 { protected: int x; public: cls1() { x=13; } }; class cls2: public cls1 { int y; public: cls2() { y=15; } int f(cls2 ob) { return (ob.x+ob.y); } }; int main() { cls2 ob; cout<
eroare: - nu exista
- lipseste namespace std si avem cout
- daca nu ar lipsi s-ar afisa 28
- se apeleaza cls1(), cls2(), cls1(ob), cls2(ob)
Spuneţi dacă programul de mai jos este corect. În caz afirmativ, spuneţi ce afişează, altfel, spuneţi de ce nu este corect. #include class cls1 { int x; public: cls1() { x=13; } int g() { static int i; i++; return (i+x); } }; class cls2 { int x; public: cls2() { x=27; } cls1& f() { static cls1 ob; return ob; } }; int main() { cls2 ob; std::cout<
- nu exista
- lipseste namespace std si avem cout
se afiseaza 14
static in funtie face sa nu se distruga obiectul la iesirea din functie
#include class cls1 { protected: int x; public: cls1(int i=10) { x=i; } int get_x() { return x; } }; class cls2: cls1 { public: cls2(int i):cls1(i) {} }; int main() { cls d(37); std::cout<
- nu exista
- lipseste namespace std si avem cout
-nu exista clasa cls
- daca acolo ar fi cls1 s-ar afisa 37
- daca acolo ar fi cls2 ar fi eraore(mostenirea e automat privata)
Ruleaza sau nu? Daca da, de ce, daca nu, de ce? #include
class Money { public: Money() : amount{ 0.0 } {}; Money(double _amount) : amount{ _amount } {};
explicit operator double() const { return amount; } private: double amount; };
void display_balance(const Money balance) { std::cout << "The balance is: " << balance << std::endl; }
Nu ruleaza pentru ca explicit la conversion opeartor previne conversia implicita catre tipul catre care se converteste.
Ruleaza sau nu? Daca da, de ce, daca nu, de ce? #include
class Money { public: Money() : amount{ 0.0 } {}; Money(double _amount) : amount{ _amount } {};
double operator double() const { return amount; } private: double amount; };
void display_balance(const Money balance) { std::cout << "The balance is: " << balance << std::endl; }
Nu ruleaza pentru ca e ilegal sa pui return type la conversion function.
Ruleaza sau nu? Daca da, de ce, daca nu, de ce? #include
class Money { public: Money() : amount{ 0.0 } {}; Money(double _amount) : amount{ _amount } {};
operator double(double x) const { return amount+x; } private: double amount; };
void display_balance(const Money balance) { std::cout << "The balance is: " << balance << std::endl; }
Nu ruleaza pentru ca e ilegal sa pui parametri ca conversion operator.
#include class cls { int x; public: cls(int y) { x=y; } int operator*(cls a,cls b) { return (a.x*b.x); } }; int main() { cls m(100),n(15); cout<
Eroare: operatorul * poate primi 0 sau 1 argument.
Spuneţi de câte ori este moştenită clasa B în clasa M1. Dar în clasa M2 ? Justificaţi.
class B { /* instructiuni */ }; class D1: virtual B { /* instructiuni */ }; class D2: virtual B { /* instructiuni */ }; class D3: B { /* instructiuni */ }; class D4: private B { /* instructiuni */ }; class D5: virtual public B { /* instructiuni */ }; class M1: D1, public D2, D3, private D4, virtual D5 { /* instructiuni */ }; class M2: D1, D2, virtual D3, virtual D4, virtual D5 { /* instructiuni */ };
Pentru M1: de 3 ori :B() D5() D1() D2() B() D3() B() D4() M1()
Pentru M2: de 3 ori B() B() D3() B() D4() D5() D1() D2() M2()
#include using namespace std; class B1 { public: int x; }; class B2 { int y; }; class B3 { public: int z; }; class B4 { public: int t; }; class D: private B1, protected B2, public B3, B4 { int u; }; int main() { D d; cout<
doar pentru z e corect
#include class cls { int vi; public: cls(int v=37) { vi=v; } friend int& f(cls); }; int& f(cls c) { return c.vi; } int main() { const cls d(15); f(d)=8; std::cout<
compileaza, dar nu se afiseaza nimic pentru ca returnez adresa unui int
#include class cls1 { public: int x; cls1(int i=20) { x=i; } }; class cls2 { public: int y; cls2(int i=30) { y=i; } operator cls1() { cls1 ob; ob.x=y; return ob; } }; cls1 f(cls1 ob) { ob.x++; return ob; } int main() { cls1 ob1; f(ob1); std::cout<
2030
#include class cls { int x; public: cls(int i=25) { x=i; } int f(); }; int cls::f() { return x; } int main() { const cls d(15); std::cout<
passing ‘const cls’ as ‘this’ argument discards qualifiers – ar trebui ca functia sa fie const si atunci s-ar afisa 15
#include class cls { public: int x; cls(int i=0) { x=i; } }; cls f(cls c) { c.x++; return c; } int main() { cls r(10); cls s=f(r); return 0; }
compileaza
#include template tip dif(tip x, tip y) { return x-y; } unsigned dif(unsigned x, unsigned y) { return x>=y?x-y:y-x; } int main() { unsigned i=7,j=8; std::cout<
afiseaza 1
#include class cls { int x; public: cls() { x=23; } int get_x() { return x; } }; int main() { cls *p1, *p2; p1=new cls; p2=(cls*)malloc(sizeof(cls)); int x=p1->get_x()+p2->get_x(); std::cout<
compileaza si afiseaza 1330860892
#include class cls1 { public: int x; cls1(int i=13) { x=i; } }; class cls2: virtual public cls1 { public: cls2(int i=15) { x=i; } }; class cls3: virtual public cls1 { public: cls3(int i=17) { x=i; } }; class cls4: public cls1 { public: cls4(int i=19) { x=i; } }; class cls5: public cls2, public cls3, public cls4 { public: int y; cls5(int i,int j):cls4(i),cls2(j) { y=i+j; } cls5(cls5& ob) { y=-ob.y; } }; int main() { cls5 ob1(-9,3), ob2=ob1; std::cout<
6
concluzie: nu trebuie neaparat sa apelezi constructorii bazelor ca sa compileze
#include class cls { int x; const int y; public: cls(int i, int j):x(i), y(j) { } int imp(int, int) const; }; int imp(int i, int j) const { x=i; y=j; return x+y; } int main() { cls ob(5); std::cout<
nu compileaza
- nu exista constructor cu un singur parametru
- imp nu are specificatorul cls::
- imp este functe const si modifica campurile
- y este const
#include class B { int a; public: B(int i=0) { a=i; } int get_a() { return a; } }; class D: private B { public: D(int x=0): B(x) {} int get_a() { return B::get_a(); } }; int main() { D d(-89); std::cout<
-89
#include class B { protected: int x; B(int i=10) { x=i; } public: virtual B operator+(B ob) { B y(x+ob.x); return y; } }; class D: public B { public: D(int i=10) { x=i; } void operator=(B p) { x=p.x; } B operator+(B ob) { B y(x+ob.x+1); return y; } void afisare() { std::cout<afisare(); return 0; }
nu compileaza
x e protected
- daca il fac pe x public afiseaza -26
- pot sa fac si un getter doar ca dupa tot o sa fie constructorul lui B protected deci trebuie sa il fac pe el public
#include class cls { public: int sa; cls(int s=0) { sa=s; } operator int() { return sa; } int f(int c) { return (sa*(1+c/100)); } }; int main() { cls p(37); std::cout<
37
#include class B { public: int x; B(int i=0) { x=i; } virtual B aduna(B ob) { return(x+ob.x); } B minus() { return(1-x); } void afisare() { std::cout<aduna(*p1); *p1=p2->minus(); p1->afisare(); return 0; }
-100
#include template class cls { tip z; public: cls(tip i) { z=i; } tip operator-(cls); }; template tip cls::operator-(cls a) { return z-a.z; } template tip dif(tip x, tip y) { return x-y; } int dif(int x, int y) { return x>=y?x-y:y-x; } int main() { cls i=3; cls j=4; std::cout<
nu compileaza
-nu e nicio functie dif cu 2 tipuri diferite
-int dif(int x, int y)
{
return x>=y?x-y:y-x;
} nu o sa funtioneze pentru ca eu apelez dif(cls, cls)
ce schimb ca sa functioneze?
#include class cls { static int x; public: cls(int i=25) { x=i; } friend int& f(cls); }; int cls::x=-13; int& f(cls c) { return c.x; } int main() { cls d(15); std::cout<
15
#include class cls { int v,nr; public: cls(int i) { nr=i; v=new int[i]; } friend int& operator[](int); friend std::ostream& operator<
nu compileaza
- operator[] must be a nonstatic member funtion => nu poate fi friend
- invalid conversion from int* to int =>trebuie ca v sa fie int*
-definitia operatorului din afara clasei nu are specificatori si nu are acceasi signatura cu cea dinauntrul clasei => varianta corecta ar fi : int& cls::operator[](int i) { return v[i]; }
acum programul rulezaza si afiseaza
13046584 13041856 0 0 83886085 7 13046584 13041856 0 0