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