Newsgroup: it.comp.lang.c++
Titolo: novellino all'opera con le classi C++

Solo oggi mi sono avvicinato all'uso delle classi C++. La mia domanda è
questa:
ho realizzato una classe Vettore nel file Vettore.h che contiene oltre le
funzioni costruttore, distruttore e accesso varie, anche la funzione membro
"prod_scal", ovvero quella che dovrebbe realizzare il prodotto scalare tra
due vettori di tipo Vettore.
La specifica è la seguente
class Vettore{
public:
//costruttore con zero argomenti
Vettore():n(0),a(new int){*a = 0;}
//costruttore che accetta in ingresso un array di n elementi
Vettore(const int);
//costruttore di copia
Vettore(const Vettore &);
//funzione che dovrebbe realizzare il prodotto scalare
int Vettore prod_scal(const Vettore &, const Vettore &);
//funzioni di servizio
void stampa();
int get_n();
private:
//vettore di tipo intero
int *a;
//numero elementi
int n;
};
Lasciando perdere l'algoritmo che realizza il prodotto scalare, il mio scopo
sarebbe quello di chiamare da main (dopo aver incluso la classe Vettore.h)
la funzione prod_scal che accetta come argomenti i vettori A e B di tipo
Vettore (precedentemente dichiarati) e restituisce il valore prodotto
scalare.
Una cosa del genere: prod_scal(A, B);
ma una chiamata del genere produce questi errori col compilatore Dev-C++:
1)implicit declaration of function `int prod_scal(...)'
2)warning: cannot pass objects of type `Vettore' through `...'
Come risolvo la cosa?
Richiesta stupida (sempre se capita) per molti, almeno spero...
Grazie.

 int prod_scal(const Vettore, const Vettore);
Ma la questione resta: come passo gli argomenti di tipo Vettore al metodo
prod_scal per farmi poi restituire un intero che sia il risultato
dell'operazione di prodotto scalare?
Grazie

"Boser" ha scritto:

Non ho controllato attentamente il tuo codice, ma penso che per quello che
vuoi fare tu convenga dichiarare la funzione prod_scal non come funzione
membro di Vettore ma come funzione libera, in questo modo:
int prod_scal(const Vettore& v1,const Vettore& v2);
Una funzione membro andrebbe chiamata su un oggetto v di tipo vettore, ma a
questo punto due parametri da passargli sono troppi: il primo vettore del
prodotto scalare è l'istanza stessa sulla quale chiami prod_scal. Quindi, se
vuoi usare prod_scal come funzione membro di Vettore, il suo prototipo
dovrebbe essere:
int prod_scal(const Vettore& altro_vettore);
Nota che in generale, per le funzioni che non modificano un parametro (di
tipo Vettore nel tuo caso), è conveniente passare tale parametro per
riferimento costante, in modo da evitare una copia dell'oggetto locale alla
funzione e allo stesso tempo non permettere un' inavvertita modifica dell'
oggetto da parte della funzione stessa.
--
imho

Il mio scopo era quello di definire una operazione di prodotto scalare da
applicare a 2 distinti vettori di tipo Vettore.
Avrei voluto ottenere la cosa chiamando da main una funzione del tipo
prod_scal(A, B); con A e B vettori di tipo Vettore. Fin qui penso sia stato
chiaro.
Sono riuscito nell'intento dichiarando una funzione friend "prod_scal" ed
implementandola direttamente nella classe (infatti se la implementavo
altrove il compilatore mi dava errore). La cosa mi č stata suggerita da una
pagina web che faceva riferimento alle funzioni friend come alle uniche che
potessero accettare in ingresso piů di un oggetto di una classe.
E' vero questo?
Nella specifica della classe definisco in questo modo la funzione suddetta:
friend int prod_scal(Vettore &v1, Vettore &v2);
e nel file delle implementazioni completo cosě:
friend Vettore prod_scal(const Vettore v1, const Vettore v2){//codice}
ma mi restituisce questi errori:
1) can't initialize friend function `prod_scal'
2) friend declaration not in class definition
La seconda di queste mi ha convinto a spostare l'implementazione della
funzione friend nella dichiarazione della classe. A questo punto il prog ha
compilato correttamente...mi aiutate a capire come devo fare!?

 2) friend declaration not in class definition
La parole chiave "friend" la devi mettere solo quando dichiari il prototipo
della funzione all'interno della tua classe, e non nel punto in cui
definisci la funzione. Inoltre nel tuo caso hai dichiarato prima la funzione
come int prod_scal (nella classe), e poi come Vettore prod_scal (nell'
implementazione). Il tipo di ritorno deve invece coincidere (in questo caso
devi mettere int al posto di Vettore). Riassumendo devi fare cosě :
- Dichiari all' interno della classe Vettore la funzione friend int
prod_scal(const Vettore& v1,const Vettore& v2);
- Definisci la funzione nel file d'implementazione cosě: int prod_scal(const
Vettore& v1,const Vettore& v2){ /*CODICE*/ }
--
imho

 Grazie
Se hai definito la funzione in questo modo all'interno della classe, hai
bisogno di un oggetto Vettore per richiamarla: supponiamo che tu voglia fare
il prodotto scalare tra due vettori a e b, dovrai fare ad esempio:
a.prod_scal(a, b)
In pratica uno dei due argomenti è ridondante, e lo puoi eliminare.
Altrimenti potresti definire la funzione esterna alla classe, ed usare la
signature che hai scritto tu, ma in questo caso per scrivere l'algoritmo
devi fare in modo di avere qualche metodo interno alla classe che ti
restituisca il valore di un elemento del vettore dato un indice (che puoi
fare o fornendo un metodo del tipo "int get(int index)" oppure ridefinendo
l'operator []).
Ciao,
Cecco

Grazie ragazzi per l'attenzione concessami...i miei errori derivavano da una
cattiva interpretazione del manuale e dall'evidente incompetenza in materia
didattica di taluni siti web.