class A {
private:
int a;
public:
A() : a{10} {}
virtual void f(ostream& str) {
str << a;
}
};
class B : public A {
private:
int a;
public:
B() : a{500} {}
void f(ostream &str) {
str << a;
}
};
int main()
{
std::unique_ptr<A> a = std::make_unique<A>();
std::unique_ptr<B> b = std::make_unique<B>();
std::unique_ptr<A> a1 = std::make_unique<B>();
a->f(cout); // 10 OK
cout << endl;
b->f(cout); // 500 OK
cout << endl;
a1->f(cout); // 500 OK
cout << endl;
A _a;
B _b;
A _a1 = B();
_a.f(cout); // 10 OK
cout << endl;
_b.f(cout); // 500 OK
cout << endl;
_a1.f(cout); // 10 WTF?!!!!
cout << endl;
return 0;
}
A _a1 = B();
- Vytvoří se dočasná proměnná typu BJavisti, boze boze...Co to je za odpověď?!!!
...
A * _a2 = &_b;
_a2->f (cout); // 500
cout << endl;
cout << "The type of _a: " << typeid(_a).name () << endl; // class A
cout << "The type of _b: " << typeid(_b).name () << endl; // class B
cout << "The type of _a1: " << typeid(_a1).name () << endl; // class A
cout << "The type of _a2: " << typeid(*_a2).name () << endl; // class B
Doporučuju přidat výpisy do konstruktorů (včetně kopírovacích) a destruktorů. Problém je tu :Vdaka za vysvetlenie!Kód: [Vybrat]A _a1 = B();
- Vytvoří se dočasná proměnná typu B
- Pomocí téhle dočasné proměnné se inicializuje proměnná _a1 typu A (tzn, zkopíruje se kus té dočasné proměnné)
- Ta dočasná proměnná typu B se zruší.
Není to chyba návrhu C++. Je to proto, že zásobník se chová jinak než halda. Na zásobníku jsou proměnné přímo. Nejsou schované za ukazatelem, který by mohl být jiného typu.
Taky jsem si tímhle WTF momentem prošel :-)Snad uz tomu rozumiem. Ja viem, ze ak mam hierarchiu A -> B -> C tak ak vytvorim instanciu objektu C ten bude v pamati zahrnovat aj podobjekty A a B. Akurat som si neuvedomil, ze ak urobim:
Podívej se na Object slicing (https://en.wikipedia.org/wiki/Object_slicing). A zamysli se nad tím, kdy se objekt kopíruje a když se přiřazuje ukazatel/reference na tu samou instanci. Vyzkoušej si to v debuggeru, napiš si pár příkladů… Funguje to prostě jinak než Java, i když syntaxe je na první pohled podobná, a taky to někdy funguje neintuitivně, pokud neznáš jak to funguje uvnitř. Většina lidí s tím má problémy, ale za vším je nějaký více či méně dobrý důvod (v horším případě historický důvod).
A a = B();
tak to co sa realne v C++ stane je, ze sa spravi kopia a objekt B sa odstrani, do premennej A sa vlozi len ten podobjekt A. Zaujimave je, ze sa to da riesit aj takto:B b;
A& _a = b;
potom to funguje tak ako ocakavam.
A& _a = b;
A* _a = &b;
Takže ke slicingu nedojde.