racanyor
06-04-2006, 20:54
ciao a tutti ragazzi, questo è il mio primo post... mi sono registrato xchè ho un problema col c++.. ho trovato un programmino che mi piacerebbe molto editare, però mi serve dividerlo in 3 file (main, file.h e file.cpp)... però il compilatore mi dà errore xchè c'è di mezzo un'istruzione stronza o.o
vi allego il codice, sperando in un aiuto
grazie mille a tutti
#include <iostream>
#include <vector>
using namespace std;
typedef vector<int> riga;
// modello della classe matrix
class matrix: public vector<riga> {
//la riga precedente significa: la classe matrix estende l'oggetto vector<riga>, ereditandone le proprieta'.
//cio' permette di usare, dalla main, espressioni come: m1[3][2], perche' il doppio indice [][] e' supportato
//dal vector<riga> e quindi automaticamente viene ereditato dalla classe matrix.
public:
matrix(int,int,int,int,int,int,int,int,int);
matrix();
void setidentity();
void print();
friend ostream& operator<< (ostream&, const matrix&);
friend matrix operator* (const int, const matrix&);
//notare che il * per scalari con il numero a sinistra non puo' essere overloadato
//alla maniera "funzioni membro", cosi' come il << (quest'ultimo perche' non siamo noi
//ad avere scritto la classe ostream!)
//in questo esempio si approccia l'overloading (dove possibile) mediante funzioni membro...
//una cosa come:
// m1 + m2;
//viene vista come:
// m1.operator+(m2);
matrix operator+ (const matrix&);
matrix& operator+= (const matrix&);
matrix operator* (const matrix&);
matrix operator* (int) const;
bool operator== (const matrix&);
};
// codice della classe matrix
matrix::matrix(){
// costruttore di default: tutti gli elementi a zero.
int i,j;
riga riga_temp;
for (i=0;i<=2;i++){
for(j=0;j<3;j++){
riga_temp.push_back(0);
}
push_back(riga_temp);
}
}
matrix::matrix(int a11, int a12, int a13, int a21, int a22, int a23, int a31, int a32, int a33){
// costruttore con valori dati nella dichiarazione
riga riga1;
riga1.push_back(a11);
riga1.push_back(a12);
riga1.push_back(a13);
riga riga2;
riga2.push_back(a21);
riga2.push_back(a22);
riga2.push_back(a23);
riga riga3;
riga3.push_back(a31);
riga3.push_back(a32);
riga3.push_back(a33);
push_back(riga1);
push_back(riga2);
push_back(riga3);
}
void matrix::setidentity(){
// imposta la matrice all'identita' 3x3
int i,j;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
(*this)[i][j]=(i==j?1:0);
// questo e' un delta di Kronecker
}
}
}
void matrix::print(){
// stampa in forma matriciale (righe e colonne: vedi l'uso di endl e di "\t")
int i,j;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
cout << (*this)[i][j] << "\t";
}
cout << endl;
}
}
//overloading degli operatori:
ostream& operator<< (ostream& os, const matrix& m){
// vedi print()
int i,j;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
os << m[i][j] << "\t";
}
os << endl;
}
// viene ritornato un *riferimento* allo stesso oggetto os che e' passato, senza farne
// una copia nuova (infatti il tipo di dato di ritorno e' ostream& e non ostream!)
return os;
}
matrix matrix::operator+ (const matrix& m2){
// anche se la funzione non modifica i valori di m1 e m2, e sarebbe indifferente
// dichiarare parametri matrix o matrix&, per evitare la creazione di due nuovi oggetti
// si preferisce usare la & (risparmiando le risorse necessarie per la copia).
// L'uso di "const" serve ad evitare che la funzione (mal scritta) sia in grado di
// modificare gli argomenti: il compilatore darebbe un errore.
// somma elemento per elemento
int i,j; // indici del risultato...
matrix sum;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
// elemento (i,j) della somma:
sum[i][j]=(*this)[i][j]+m2[i][j];
}
}
// viene ritornato un *nuovo* oggetto di tipo matrix! (non c'e' & dopo matrix nel tipo
// di ritorno)
return sum;
}
matrix& matrix::operator+= (const matrix& m_source){
// ecco un caso in cui m_source non viene modificata (ed e' const), mentre i valori di
// m_dest vanno modificati, e non si usa la parola chiave const. Inoltre, la funzione
// in se' rende a sua volta un riferimento a m_dest per permettere espressioni come:
// m3 = (m2+=m1);
// Il valore di ritorno non viene usato da istruzioni come:
// m5+=m4;
// appoggiandosi all'operatore +, gia' overloadato, basta scrivere:
(*this) = (*this) + m_source;
return (*this);
}
matrix matrix::operator* (const matrix& m2){
//prodotto tra matrici: la formula richiede l'uso di tre indici...
int i,j; // indici del risultato...
int k; // questo per il calcolo dell'elemento della matrice prodotto
int temp;
matrix prod;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
// elemento (i,j) del prodotto:
temp=0;
for (k=0;k<=2;k++){
temp+=(*this)[i][k]*m2[k][j];
}
prod[i][j]=temp;
}
}
return prod;
}
matrix operator* (int number, const matrix& m2){
return m2 * number;
}
matrix matrix::operator* (const int number) const{
// prodotto per scalari
// come per il costructor, possono convivere piu' funzioni con lo stesso nome,
// con identico tipo di dato di ritorno, ma diversi argomenti: il compilatore
// si occupera' di chiamare di volta in volta la corretta versione della funzione;
// cosi' e' risolta l'ambiguita' tra (matrix)*(matrix) e (int)*(matrix), ovvero
// tra prodotto tra matrici e per scalari.
int i,j; // indici del risultato...
matrix scalar_prod;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
scalar_prod[i][j]=(*this)[i][j]*number;
}
}
return scalar_prod;
}
bool matrix::operator== (const matrix& m2){
//serve ad estendere l'operatore == ad oggetti matrix, rendendo vero
// se e solo se gli elementi coincidono uno ad uno.
bool sofar = true;
int i,j;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
if ((*this)[i][j] != m2[i][j]) sofar = false;
}
}
return sofar;
}
/****************************************************************************************
* *
* FINE CLASSE - INIZIO MAIN DI ESEMPIO *
* *
*****************************************************************************************/
int main(){
matrix m1;
matrix m2(1,2,3,4,5,6,7,8,9);
cout << "-> Stampa m2:\n";
m2.print();
cout << "\n-> Stampa m1:\n";
m1.print();
cout << "\n\n-> Stampa dell'elemento (2,2) di m2 con m2[2][2]:\n";
cout << m2[2][2];
cout << "\n\n-> SetIdentity e stampa di m1:\n";
m1.setidentity();
m1.print();
cout << "\n\n-> Set di un -1 in (1,1):\n";
m1[1][1]=-1;
m1.print();
cout << "\n\n-> Stampa con << di m2...\n" << m2 << endl;
matrix m3 = m1 + m2;
cout << "\n\n-> Somma di m1 e m2 = m3:\n";
m3.print();
m3+=m2;
cout << "\n\n-> Risultato di m3+=m2: m3 =\n";
cout << m3 << endl;
matrix m4 = m3 * m2;
cout << "\n\n-> Prodotto di m3 e m2 = m4:\n";
m4.print();
matrix m5 = -2 * m4;
cout << "\n\n-> Prodotto di -2 e m4 (per scalari):\n";
m5.print();
cout << "\n\n-> Confronti: (m1==m2) da': " << (m1==m2) << endl
<< "-> invece (m2==m2) da': " << (m2==m2) << endl;
cout << "\n=> Grazie per avere utilizzato questo divertente programma.\n";
system ("PAUSE");
return 0;
}
:muro:
vi allego il codice, sperando in un aiuto
grazie mille a tutti
#include <iostream>
#include <vector>
using namespace std;
typedef vector<int> riga;
// modello della classe matrix
class matrix: public vector<riga> {
//la riga precedente significa: la classe matrix estende l'oggetto vector<riga>, ereditandone le proprieta'.
//cio' permette di usare, dalla main, espressioni come: m1[3][2], perche' il doppio indice [][] e' supportato
//dal vector<riga> e quindi automaticamente viene ereditato dalla classe matrix.
public:
matrix(int,int,int,int,int,int,int,int,int);
matrix();
void setidentity();
void print();
friend ostream& operator<< (ostream&, const matrix&);
friend matrix operator* (const int, const matrix&);
//notare che il * per scalari con il numero a sinistra non puo' essere overloadato
//alla maniera "funzioni membro", cosi' come il << (quest'ultimo perche' non siamo noi
//ad avere scritto la classe ostream!)
//in questo esempio si approccia l'overloading (dove possibile) mediante funzioni membro...
//una cosa come:
// m1 + m2;
//viene vista come:
// m1.operator+(m2);
matrix operator+ (const matrix&);
matrix& operator+= (const matrix&);
matrix operator* (const matrix&);
matrix operator* (int) const;
bool operator== (const matrix&);
};
// codice della classe matrix
matrix::matrix(){
// costruttore di default: tutti gli elementi a zero.
int i,j;
riga riga_temp;
for (i=0;i<=2;i++){
for(j=0;j<3;j++){
riga_temp.push_back(0);
}
push_back(riga_temp);
}
}
matrix::matrix(int a11, int a12, int a13, int a21, int a22, int a23, int a31, int a32, int a33){
// costruttore con valori dati nella dichiarazione
riga riga1;
riga1.push_back(a11);
riga1.push_back(a12);
riga1.push_back(a13);
riga riga2;
riga2.push_back(a21);
riga2.push_back(a22);
riga2.push_back(a23);
riga riga3;
riga3.push_back(a31);
riga3.push_back(a32);
riga3.push_back(a33);
push_back(riga1);
push_back(riga2);
push_back(riga3);
}
void matrix::setidentity(){
// imposta la matrice all'identita' 3x3
int i,j;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
(*this)[i][j]=(i==j?1:0);
// questo e' un delta di Kronecker
}
}
}
void matrix::print(){
// stampa in forma matriciale (righe e colonne: vedi l'uso di endl e di "\t")
int i,j;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
cout << (*this)[i][j] << "\t";
}
cout << endl;
}
}
//overloading degli operatori:
ostream& operator<< (ostream& os, const matrix& m){
// vedi print()
int i,j;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
os << m[i][j] << "\t";
}
os << endl;
}
// viene ritornato un *riferimento* allo stesso oggetto os che e' passato, senza farne
// una copia nuova (infatti il tipo di dato di ritorno e' ostream& e non ostream!)
return os;
}
matrix matrix::operator+ (const matrix& m2){
// anche se la funzione non modifica i valori di m1 e m2, e sarebbe indifferente
// dichiarare parametri matrix o matrix&, per evitare la creazione di due nuovi oggetti
// si preferisce usare la & (risparmiando le risorse necessarie per la copia).
// L'uso di "const" serve ad evitare che la funzione (mal scritta) sia in grado di
// modificare gli argomenti: il compilatore darebbe un errore.
// somma elemento per elemento
int i,j; // indici del risultato...
matrix sum;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
// elemento (i,j) della somma:
sum[i][j]=(*this)[i][j]+m2[i][j];
}
}
// viene ritornato un *nuovo* oggetto di tipo matrix! (non c'e' & dopo matrix nel tipo
// di ritorno)
return sum;
}
matrix& matrix::operator+= (const matrix& m_source){
// ecco un caso in cui m_source non viene modificata (ed e' const), mentre i valori di
// m_dest vanno modificati, e non si usa la parola chiave const. Inoltre, la funzione
// in se' rende a sua volta un riferimento a m_dest per permettere espressioni come:
// m3 = (m2+=m1);
// Il valore di ritorno non viene usato da istruzioni come:
// m5+=m4;
// appoggiandosi all'operatore +, gia' overloadato, basta scrivere:
(*this) = (*this) + m_source;
return (*this);
}
matrix matrix::operator* (const matrix& m2){
//prodotto tra matrici: la formula richiede l'uso di tre indici...
int i,j; // indici del risultato...
int k; // questo per il calcolo dell'elemento della matrice prodotto
int temp;
matrix prod;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
// elemento (i,j) del prodotto:
temp=0;
for (k=0;k<=2;k++){
temp+=(*this)[i][k]*m2[k][j];
}
prod[i][j]=temp;
}
}
return prod;
}
matrix operator* (int number, const matrix& m2){
return m2 * number;
}
matrix matrix::operator* (const int number) const{
// prodotto per scalari
// come per il costructor, possono convivere piu' funzioni con lo stesso nome,
// con identico tipo di dato di ritorno, ma diversi argomenti: il compilatore
// si occupera' di chiamare di volta in volta la corretta versione della funzione;
// cosi' e' risolta l'ambiguita' tra (matrix)*(matrix) e (int)*(matrix), ovvero
// tra prodotto tra matrici e per scalari.
int i,j; // indici del risultato...
matrix scalar_prod;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
scalar_prod[i][j]=(*this)[i][j]*number;
}
}
return scalar_prod;
}
bool matrix::operator== (const matrix& m2){
//serve ad estendere l'operatore == ad oggetti matrix, rendendo vero
// se e solo se gli elementi coincidono uno ad uno.
bool sofar = true;
int i,j;
for (i=0;i<=2;i++){
for (j=0;j<=2;j++){
if ((*this)[i][j] != m2[i][j]) sofar = false;
}
}
return sofar;
}
/****************************************************************************************
* *
* FINE CLASSE - INIZIO MAIN DI ESEMPIO *
* *
*****************************************************************************************/
int main(){
matrix m1;
matrix m2(1,2,3,4,5,6,7,8,9);
cout << "-> Stampa m2:\n";
m2.print();
cout << "\n-> Stampa m1:\n";
m1.print();
cout << "\n\n-> Stampa dell'elemento (2,2) di m2 con m2[2][2]:\n";
cout << m2[2][2];
cout << "\n\n-> SetIdentity e stampa di m1:\n";
m1.setidentity();
m1.print();
cout << "\n\n-> Set di un -1 in (1,1):\n";
m1[1][1]=-1;
m1.print();
cout << "\n\n-> Stampa con << di m2...\n" << m2 << endl;
matrix m3 = m1 + m2;
cout << "\n\n-> Somma di m1 e m2 = m3:\n";
m3.print();
m3+=m2;
cout << "\n\n-> Risultato di m3+=m2: m3 =\n";
cout << m3 << endl;
matrix m4 = m3 * m2;
cout << "\n\n-> Prodotto di m3 e m2 = m4:\n";
m4.print();
matrix m5 = -2 * m4;
cout << "\n\n-> Prodotto di -2 e m4 (per scalari):\n";
m5.print();
cout << "\n\n-> Confronti: (m1==m2) da': " << (m1==m2) << endl
<< "-> invece (m2==m2) da': " << (m2==m2) << endl;
cout << "\n=> Grazie per avere utilizzato questo divertente programma.\n";
system ("PAUSE");
return 0;
}
:muro: