mirror of https://github.com/xfarrow/lasd.git
Lezione 5
This commit is contained in:
parent
a0fc2e6e6d
commit
bfc9b6ecd3
Binary file not shown.
|
@ -0,0 +1,51 @@
|
||||||
|
#include<iostream>
|
||||||
|
using namespace std;
|
||||||
|
class A{
|
||||||
|
public:
|
||||||
|
int x;
|
||||||
|
A(){
|
||||||
|
cout<<"Sono nel costruttore di A"<<endl;
|
||||||
|
x = x+1;
|
||||||
|
}
|
||||||
|
A(const A& a){
|
||||||
|
cout<<"Sono nel costruttore di copia di A"<<endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class B:public A{
|
||||||
|
public:
|
||||||
|
B(){
|
||||||
|
cout<<"Sono nel costruttore di B"<<endl;
|
||||||
|
x+=100;
|
||||||
|
}
|
||||||
|
B(const B& b){
|
||||||
|
cout<<"Sono nel costruttore di copia di B"<<endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class C:public B{
|
||||||
|
public:
|
||||||
|
C(){
|
||||||
|
cout<<"Sono nel costruttore di C"<<endl;
|
||||||
|
x+=1000;
|
||||||
|
}
|
||||||
|
C(const C& c){
|
||||||
|
cout<<"Sono nel costruttore di copia di C"<<endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
int main(){
|
||||||
|
/*
|
||||||
|
Sono nel costruttore di A
|
||||||
|
Sono nel costruttore di B
|
||||||
|
Sono nel costruttore di C
|
||||||
|
*/
|
||||||
|
C obj;
|
||||||
|
|
||||||
|
cout<<endl;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sono nel costruttore di A
|
||||||
|
Sono nel costruttore di B
|
||||||
|
Sono nel costruttore DI COPIA di C
|
||||||
|
*/
|
||||||
|
C obj2(obj);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include<iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void problema();
|
||||||
|
void soluzione();
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
//problema();
|
||||||
|
soluzione();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void problema(){
|
||||||
|
class A{
|
||||||
|
public:
|
||||||
|
int* v = new int[10];
|
||||||
|
~A(){
|
||||||
|
cout<<"Richiamato distuttore di A"<<endl;
|
||||||
|
delete[] v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class B: public A{
|
||||||
|
public:
|
||||||
|
char* s = new char[20];
|
||||||
|
~B(){
|
||||||
|
cout<<"Richiamato distruttore di B"<<endl;
|
||||||
|
delete[] s;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
A* ptr = new B(); //dato che B è anche un tipo A, questo può essere fatto.
|
||||||
|
delete ptr; // "Richiamato distruttore di A"
|
||||||
|
/*
|
||||||
|
Creo un oggetto B (quindi che contiene anche A) e lo assegno a un puntatore
|
||||||
|
a oggetto A.
|
||||||
|
Se poi faccio "delete ptr" il compilatore va a richiamare il distruttore di A
|
||||||
|
e non anche quello di B. Quindi l'array di char "s" rimarrà in memoria almeno
|
||||||
|
fino al termine del programma.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void soluzione(){
|
||||||
|
class A{
|
||||||
|
public:
|
||||||
|
int* v = new int[10];
|
||||||
|
/*
|
||||||
|
Virtual functions ensure that the correct function is called for an object,
|
||||||
|
regardless of the type of reference (or pointer) used for function call.
|
||||||
|
https://www.geeksforgeeks.org/virtual-function-cpp/
|
||||||
|
*/
|
||||||
|
virtual ~A(){ // metodo virtuale. Deve essere sempre fatto così sui distruttori.
|
||||||
|
cout<<"Richiamato distuttore di A"<<endl;
|
||||||
|
delete[] v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class B: public A{
|
||||||
|
public:
|
||||||
|
char* s = new char[20];
|
||||||
|
~B(){
|
||||||
|
cout<<"Richiamato distruttore di B"<<endl;
|
||||||
|
delete[] s;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
A* ptr = new B(); //dato che B è anche un tipo A, questo può essere fatto.
|
||||||
|
delete ptr; // "Richiamato distruttore di B Richiamato distuttore di A"
|
||||||
|
}
|
|
@ -10,5 +10,41 @@
|
||||||
= 0: pure virtual. A questo livello l'implementazione di questo metodo non esiste
|
= 0: pure virtual. A questo livello l'implementazione di questo metodo non esiste
|
||||||
= default: ammesso solo per cost. e dist. che dice di creare quelli di default
|
= default: ammesso solo per cost. e dist. che dice di creare quelli di default
|
||||||
=delete: elimina un metodo precedentemente scritto nella gerarchia
|
=delete: elimina un metodo precedentemente scritto nella gerarchia
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
Il corpo di una funzione può essere messo anche fuori dalla classe:
|
||||||
|
*/
|
||||||
|
#include<iostream>
|
||||||
|
class ClassName{
|
||||||
|
private:
|
||||||
|
int y = 5;
|
||||||
|
public:
|
||||||
|
int x = 3;
|
||||||
|
|
||||||
|
int aggiungiX(int); // dichiarazione funzione
|
||||||
|
|
||||||
|
int aggiungiY(int); // dichiarazione funzione
|
||||||
|
friend int aggiungiY(int); // dichiarazione friendship
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
NB: in questo caso x deve essere dichiarata pubblica. Se fosse stato un metodo
|
||||||
|
all'interno della classe allora avrebbe potuto avere accesso anche se x
|
||||||
|
fosse stata privata
|
||||||
|
*/
|
||||||
|
int ClassName::aggiungiX(int parametro){
|
||||||
|
x+=parametro;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Oppure si può dichiarare la friendship per accedere a variabili private/protette
|
||||||
|
*/
|
||||||
|
int ClassName::aggiungiY(int parametro){
|
||||||
|
y+=parametro;
|
||||||
|
std::cout<<y<<std::endl;
|
||||||
|
}
|
||||||
|
int main(){
|
||||||
|
ClassName obj;
|
||||||
|
obj.aggiungiX(7);
|
||||||
|
obj.aggiungiY(9);
|
||||||
|
std::cout<<obj.x<<std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
#include<iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
/*
|
||||||
|
ereditarietà a diamante:
|
||||||
|
A <-- B
|
||||||
|
A <-- C
|
||||||
|
B <-- D
|
||||||
|
C <-- D
|
||||||
|
*/
|
||||||
|
|
||||||
|
class A{
|
||||||
|
public:
|
||||||
|
int a;
|
||||||
|
A(){
|
||||||
|
cout<<"A created"<<endl;
|
||||||
|
}
|
||||||
|
~A(){
|
||||||
|
cout<<"A destroyed"<<endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class B : A{
|
||||||
|
public:
|
||||||
|
int b;
|
||||||
|
B(){
|
||||||
|
cout<<"B created"<<endl;
|
||||||
|
}
|
||||||
|
~B(){
|
||||||
|
cout<<"B destroyed"<<endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class C : A{
|
||||||
|
public:
|
||||||
|
int c;
|
||||||
|
C(){
|
||||||
|
cout<<"C created"<<endl;
|
||||||
|
}
|
||||||
|
~C(){
|
||||||
|
cout<<"C destroyed"<<endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class D : B,C{
|
||||||
|
public:
|
||||||
|
int d;
|
||||||
|
D(){
|
||||||
|
cout<<"D created"<<endl;
|
||||||
|
}
|
||||||
|
~D(){
|
||||||
|
cout<<"D destroyed"<<endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
/*
|
||||||
|
Ogni oggetto deve avere all'interno gli oggetti ereditati. Quindi stampa:
|
||||||
|
A created (per creare D mi serve prima B. Per creare B mi serve prima A)
|
||||||
|
B created (creato A, posso creare B)
|
||||||
|
A created (per creare D mi serve prima C. Per creare C mi serve prima A)
|
||||||
|
C created (creato A, posso creare C)
|
||||||
|
D created (creato B che contiene A e creato C che contiene A, posso creare D)
|
||||||
|
*/
|
||||||
|
D obj;
|
||||||
|
cout<<endl;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
La distruzione viene effettuata al contrario
|
||||||
|
D destroyed
|
||||||
|
C destroyed
|
||||||
|
A destroyed
|
||||||
|
B destroyed
|
||||||
|
A destroyed
|
||||||
|
*/
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
#include<iostream>
|
||||||
|
using namespace std;
|
||||||
|
/*
|
||||||
|
ereditarietà a diamante:
|
||||||
|
A <-- B
|
||||||
|
A <-- C
|
||||||
|
B <-- D
|
||||||
|
C <-- D
|
||||||
|
*/
|
||||||
|
|
||||||
|
void nonVirtualInheritance();
|
||||||
|
void virtualInheritance();
|
||||||
|
int main(){
|
||||||
|
//nonVirtualInheritance();
|
||||||
|
virtualInheritance();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nonVirtualInheritance(){
|
||||||
|
class A{
|
||||||
|
public:
|
||||||
|
int size = 7;
|
||||||
|
};
|
||||||
|
|
||||||
|
class B : public A{
|
||||||
|
public:
|
||||||
|
int b;
|
||||||
|
};
|
||||||
|
|
||||||
|
class C : public A{
|
||||||
|
public:
|
||||||
|
int c;
|
||||||
|
};
|
||||||
|
|
||||||
|
class D : public B, public C{
|
||||||
|
public:
|
||||||
|
int d;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Adesso B ha una copia di A, C ha una copia di A, D ha una copia di B e una
|
||||||
|
copia di C. Implica che D ha due copie di A.
|
||||||
|
Se provo a stampare size, cosa succede?
|
||||||
|
*/
|
||||||
|
D obj;
|
||||||
|
//cout<<obj.size<<endl; //request for member ‘size’ is ambiguous
|
||||||
|
|
||||||
|
cout<<obj.B::size<<endl;
|
||||||
|
cout<<obj.C::size<<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void virtualInheritance(){
|
||||||
|
class A{
|
||||||
|
public:
|
||||||
|
int size = 7;
|
||||||
|
};
|
||||||
|
|
||||||
|
class B : virtual public A{
|
||||||
|
public:
|
||||||
|
int b;
|
||||||
|
};
|
||||||
|
|
||||||
|
class C :virtual public A{
|
||||||
|
public:
|
||||||
|
int c;
|
||||||
|
};
|
||||||
|
|
||||||
|
class D : public B, public C{
|
||||||
|
public:
|
||||||
|
int d;
|
||||||
|
};
|
||||||
|
|
||||||
|
D obj;
|
||||||
|
cout<<obj.size; // adesso posso stampare tranquillamente size
|
||||||
|
|
||||||
|
/*
|
||||||
|
Questo è possibile grazie al fatto che B e C ereditano A in modo virtuale,
|
||||||
|
ovverosia, c'è solo un'istanza A condivisa tra B e C.
|
||||||
|
https://www.cprogramming.com/tutorial/virtual_inheritance.html
|
||||||
|
*/
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
#include<iostream>
|
||||||
|
using namespace std;
|
||||||
|
class A{
|
||||||
|
private:
|
||||||
|
int a = 1;
|
||||||
|
protected:
|
||||||
|
int b = 2;
|
||||||
|
public:
|
||||||
|
int c = 3;
|
||||||
|
int sameVariable = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
class B : A{
|
||||||
|
public:
|
||||||
|
int sameVariable = 9;
|
||||||
|
void test(){
|
||||||
|
//cout<<a<<endl; // errore, "a" è privata
|
||||||
|
cout<<b<<endl; // 2
|
||||||
|
cout<<c<<endl; // 3
|
||||||
|
cout<<sameVariable<<endl; // 9
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
B b;
|
||||||
|
b.test();
|
||||||
|
//cout<<b.a<<endl; //NO
|
||||||
|
//cout<<b.b<<endl; //NO
|
||||||
|
|
||||||
|
/*
|
||||||
|
Benché A::c sia pubblica, non posso accedergli da qua perché di default
|
||||||
|
l'ereditarietà viene fatta in modo privato.
|
||||||
|
Se avessi scritto class B:public A allora avrei potuto stampare.
|
||||||
|
*/
|
||||||
|
//cout<<b.c<<endl; //NO
|
||||||
|
cout<<b.sameVariable<<endl; // 9
|
||||||
|
|
||||||
|
/*
|
||||||
|
Se l'ereditarietà fosse stata pubblica (B: public A) avrei potuto scrivere
|
||||||
|
cout<<b.A::sameVariable<<endl;
|
||||||
|
per eccedere a "sameVariable" di A
|
||||||
|
*/
|
||||||
|
}
|
Binary file not shown.
Loading…
Reference in New Issue