Classi in C++ Console Application

/*
  Autore: Prof. Alessandro Barazzuol
  Data: Esempio sulle classi
  Copyright "© Alessandro Barazzuol
  Motore: Mingw porting di GCC
  Versione: Debug o Relase se finita
  
*/

#include<iostream>//I/O
#include<cstdlib> //nomi srand e rand
#include<ctime>//orologio di sistema
#include<string>
using namespace std;

class A
{
	protected:
		
		int ereditatov;
		char ereditatoc;
		string nomeclasse;
		
	private:
		
		char c;
		int v;

	public:
	
		static int noggetti;	
		
		static void guida()
		{
			cout<<"Sono la guida e funziono anche senza istanziare un oggetto\n";
		}
				
	A()
	{
		cout<<"Passo per A per costruire un oggetto di A, ma";
		cout<<"..anche per costruire un oggetto di B, passo per A\n";
		nomeclasse="classe A";
		noggetti++;
	}
	
	A(char c, int v)
	{
		this->c=c;
		this->v=v;
	}
	
	
	
	int get_v()
	{
		cout<<"Sono il metodo get_v della classe A\n";
		return v;
	}
	
	
	char get_c()
	{
		return c;
	}
	
	
	virtual void qualcosa()//metodo virtuale che  potrebbe anche non essere implementato 
	                       //serve per capire il metodo da eseguire perchè non sempre vale la regola della dominanza
	{
		cout<<"Provengo da A "<<nomeclasse<<endl;
	}
	
	
	friend void usaA(A &a);//funzione definita nella classe, ma implementata fuori della classe, deve essere friend per accedere ai sui attributi privati
	
};


void usaA(A &a)
{
	//essendo friend vede gli attributi privati
	cout<<"Sono esterna alla classe A e sto usando un attributo privato di A : v ="<<a.v<<endl;
	cout<<"Sono esterna alla classe A, ed eseguo il metodo della classe di appartenenza dell'oggetto "<<" classe : "<<a.nomeclasse<<endl;
}


//clsse B che deriva da A. eredita tutto il public e il protected
class B:public A
{
	private:
		int b;//attributo che A non ha e vale solo per la classe B
	
	protected:
		//ulterori attributi che verranno ereditati da altre sottocolassi
	
	
	public:
		//normalmente per costruire un oggetto di B, passa per A(), ma se fosse :A('A',8) cosi  passa per A(char c, int v)
		B()//:A('A',8) vorrebbe dire che il costruttore di B non passa per A() ma per A(char c, int v)
		{
			nomeclasse="classe B";
			noggetti++;
		}
		
	//overload del metodo int get_v
	int get_v(int g)
    {
    	return g*ereditatov;
	}
	
	//overriding del metodo get_v
	int get_v()
	{
		
		//se voglio che faccia prima anche get_v di A, allora scrivo A::get_v(); cosi passa prima per A
	
		cout<<"Sono il metodo get_v della classe B, in overriding e sono stato chiamato dalla classe B, faccio v*v*v = "<<ereditatov*ereditatov*ereditatov<<"\n";
		return ereditatov*ereditatov*ereditatov;
		
	}
	
	
	//ovverriding del metodo virtuale
	void qualcosa()
	{
		cout<<"Provengo da B "<<nomeclasse<<endl;
	}
	
	
};



//funzione che riceve un oggetto della classe, ma non nessendo friend non può vedere le cose private
void chi(A *a)
{
a->qualcosa();
}


int A::noggetti=0;//gli attributi statici vanno azzerrati fuori della classe e prima del main

int main()
{

for(int i=0;i<3;i++)
A *a=new A();

cout<<"Ho creato n = "<<A::noggetti<<" oggetti di A "<<endl;
cout<<"Per ora ho creato n = "<<B::noggetti<<" oggetti di B "<<endl;

for(int i=0;i<3;i++)
B *b=new B();

cout<<"Ho creato n = "<<A::noggetti<<" oggetti di A "<<endl;
cout<<"Per ora ho creato n = "<<B::noggetti<<" oggetti di B "<<endl;

A *a=new A();
B *b=new B();
chi(b);//se il metodo qualcosa non fosse virtual eseguirebbe la classe A

b->get_v();



return 0;

}