prototype for ‘Wiel Wiel::pochodna()’ does not match any - błąd kompilacji

0

Próbuję napisać sobie program następujący:

wiel_prog.cpp
[code]
#include <iostream>
#include "wiel.h"

int main()
{
//1 p.

cout<<endl<<"------   ETAP 1   ------"<<endl;
double tab1[]={1,2,3,4}; // w(x)=4*x<sup>3+3*x</sup>2+2*x<sup>1+1*x</sup>0
Wiel w1(3,tab1);         // stopieñ wielomianu
                         // oraz tablica wspó³czynników
cout<<"w1(x)="<<w1<<endl;

//0.5 p.

cout<<endl<<"------   ETAP 2   ------"<<endl;
Wiel w2(w1),w3;
cout<<"w2(x)="<<w2<<endl;
cout<<"w3(x)="<<w3<<endl;

//0.5 p.

cout<<endl<<"------   ETAP 3   ------"<<endl;
w3=w2;
cout<<"w3(x)="<<w3<<endl;
w2[3]=2;
cout<<"w2(x)="<<w2<<endl;

//1 p.

cout<<endl<<"------   ETAP 4   ------"<<endl;
double x=2;
cout<<"w1(x)="<<w1<<endl;
cout<<"w1(2)="<<w1(x)<<endl; // wartoϾ wielomianu
                             // dla argumentu x=2
                             // zastosuj algorytm Hornera

//1 p.

cout<<endl<<"------   ETAP 5   ------"<<endl;
w3=w1.pochodna();

cout<<"w1(x)     = "<<w1<<endl;
cout<<"w1'(x)    = "<<w3<<endl;
cout<<"w1'(2)="<<w3(x)<<endl;
Wiel w4 = w3.pochodna();
cout<<"w1''(x)   = "<<w4<<endl;
w4 = w4.pochodna();
cout<<"w1`(x)  = "<<w4<<endl;
w4 = w4.pochodna();
cout<<"w1`'(x) = "<<w4<<endl;
w4 = w4.pochodna();
cout<<"w1`''(x)= "<<w4<<endl;

//0.5 p.
/*
cout<<endl<<"------ ETAP 6 ------"<<endl;
cout<<"w1(x)="<<w1<<endl;
cout<<"w3(x)="<<w3<<endl;
w4=w3+w1; cout<<"w4(x)=w3(x)+w1(x)="<<w4<<endl;
/
//0.5 p.
/

cout<<endl<<"------ ETAP 7 ------"<<endl;
//WSKAZOWKA: zdefiniuj i wykorzystaj metode prywatna:
// Wiel& operator-();
w4=w1-w3; cout<<"w4(x)=w1(x)-w3(x)="<<w4<<endl;
w4=w3-w1; cout<<"w4(x)=w3(x)-w1(x)="<<w4<<endl;
w4=w3-w3; cout<<"w4(x)=w3(x)-w1(x)="<<w4<<endl;
*/
return 0;
}

[/code]

wiel.cpp
[code]
#include "wiel.h"

using namespace std;

void log (char *);

void log (char *string)
{
cerr << string << endl;
}

Wiel::Wiel (Wiel &c)
{
this->n = c.n;
this->a = new double[n+1];
for (int i = 0; i<=c.n; i++)
this->a[i] = c.a[i];
}

Wiel::Wiel (int n, double *tab)
{
if (n<=0)
{
throw(-1);
log ("Nie mogę utworzyć mniejszej niż 0");
}
this->n = n;
cerr << "tworzę wielomian stopnia " << n;

this->a = new double[this->n+1];
for (int i = 0; i<=this->n; i++) this->a[i] = tab[i];
cerr << "Tworzę wielomian z tablica " << this->a << endl;

}

Wiel::Wiel (int n)
{
if (n<=0) throw (-1);
this->n = n;
cerr << "tworzę wielomian stopnia " << n;
this->a = new double[this->n+1];
for (int i = 0; i<=this->n; i++)
this->a[i] = 0;

cerr << "Tworzę wielomian z tablica " << this->a << endl;

}

Wiel::Wiel ()
{
this->n = 0;
cerr << "tworzę wielomian stopnia " << n;
this->a = NULL;
cerr << "Tworzę wielomian z tablica " << this->a << endl;
}

Wiel::~Wiel()
{
if (this->a != NULL) delete []a;
}

ostream& operator << ( ostream& c, const Wiel& w)
{
if (w.n > 0)
{
for (int i = 0; i<w.n; i++)
cout << w.a[i] << "*x^" << w.n-i << " + ";
cout << w.a[w.n] << "*x^0" << endl;
} else cout << " 0 ";
return c;
}

double& Wiel::operator[] (int i)
{
// błąd
if (i<=this->n) return this->a[i]; else throw(-1);
}

Wiel& Wiel::operator= (Wiel& rhs)
{
//błąd
this->n = rhs.n;
if (this->a != NULL) delete[] this->a;
this->a = new double[rhs.n+1];
for (int i = 0; i<=rhs.n; i++)
this->a[i] = rhs.a[i];
return *this;
}

double& Wiel::operator() (int n)
{
double var = this->a[this->n];
for (int i = n-1; i>=0; i--)
var += var*n + this->a[i];
return var;
}

Wiel Wiel::pochodna ()
{
// błąd
Wiel nowy(this->n-1);
cout << "Stary: " << this << endl;
for (int i = 0; i<=nowy.n; i++)
nowy.a[i] = this->a[i]
(n-i);

return nowy;

}

/* Wiel Wiel::operator+ (Wiel& rhs)
{
int m;
Wiel nowy (max(this->n, rhs.n), rhs.a);
for (int i = nowy.n; i>=min(this->n, rhs.n); i--)
{
nowy->a[i] += rhs.i;
}

for (i = 0; i<=nowy.n; i++)
    if (nowy.a[i] !=0 )
        {
            m = i;
            break;
        }

Wiel nowy2(i, nowy.a);
return nowy2;

}

Wiel Wiel::operator- (Wiel& rhs)
{
int m;
Wiel nowy (max(this->n, rhs.n), rhs.a);
for (int i = 0; i<nowy.n; i++)
nowy[i] = rhs[i];
for (int i = n; i>=0; i--)
if (nowy[i]!=0)
{
m = i;
break;
}
Wiel nowy2 (m, nowy.a);
return nowy2;
}

*/

[/code]

wiel.h
[code]
#include <iostream>

using namespace std;

class Wiel
{
int n; // stopień wielomianu
double* a; // tablica współczynników wielomianu
// w(x)=a[n]*xn+a[n-1]*x(n-1)+...+a[1]*x1+a[0]*x0
public:
//.............................................
//.............................................

Wiel (int, double *);
Wiel (Wiel&);
Wiel (int n);
Wiel ();
~Wiel ();
friend ostream& operator << ( ostream&, const Wiel& );
double& operator[] (int n);
Wiel& operator= (Wiel&);
double& operator() (int n);
Wiel& pochodna ();

Wiel operator+ (Wiel& rhs);
Wiel operator- (Wiel& rhs);

};

[/code]

Przy kompilacji wyrzuca to:

[quote]
== xxxtemp, Debug ===

/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.cpp||In constructor ‘Wiel::Wiel(int, double*)’:|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.cpp|25|warning: deprecated conversion from string constant to ‘char*’|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.cpp||In member function ‘double& Wiel::operator()(int)’:|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.cpp|93|warning: reference to local variable ‘var’ returned|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.cpp|99|error: prototype for ‘Wiel Wiel::pochodna()’ does not match any in class ‘Wiel’|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.h|23|error: candidate is: Wiel& Wiel::pochodna()|
== Build finished: 2 errors, 2 warnings ===

[/quote]

Co robię nie tak? Gdy próbowałem zamienić referencję na zwykły obiekt, program kompilował się, ale pojawiał się też run-time error, przy przypisywaniu za pomocą operator= (null pointer w tablicy double)

0

Oddziel te dwa błędy. Po pierwsze zmień definicję (plik .h) procedury pochodna, ponieważ ma zwracać nowy obiekt, a nie referencję. Dodatkowo zmień operator(), żeby także zwracał wartość, a nie referencję. Jak nadal będziesz miał błędy to napisz, ale teraz nikt tego nie będzie testował za ciebie (za dużo kodu).

0

Poprawiłem pochodna, operator= na zwrot obiektów (z ref.) i nadal wyświetla błędy:

[quote]
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.cpp||In constructor ‘Wiel::Wiel(int, double*)’:|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.cpp|25|warning: deprecated conversion from string constant to ‘char*’|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.cpp||In member function ‘double& Wiel::operator()(int)’:|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.cpp|93|warning: reference to local variable ‘var’ returned|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel_prog.cpp||In function ‘int main()’:|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel_prog.cpp|41|error: no match for ‘operator=’ in ‘w3 = Wiel::pochodna()()’|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.h|21|note: candidates are: Wiel Wiel::operator=(Wiel&)|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel_prog.cpp|46|error: no matching function for call to ‘Wiel::Wiel(Wiel)’|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.h|17|note: candidates are: Wiel::Wiel()|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.h|16|note: Wiel::Wiel(int)|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.h|15|note: Wiel::Wiel(Wiel&)|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.h|14|note: Wiel::Wiel(int, double*)|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel_prog.cpp|48|error: no match for ‘operator=’ in ‘w4 = Wiel::pochodna()()’|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.h|21|note: candidates are: Wiel Wiel::operator=(Wiel&)|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel_prog.cpp|50|error: no match for ‘operator=’ in ‘w4 = Wiel::pochodna()()’|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.h|21|note: candidates are: Wiel Wiel::operator=(Wiel&)|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel_prog.cpp|52|error: no match for ‘operator=’ in ‘w4 = Wiel::pochodna()()’|
/home/tomasz/Dokumenty/prace/c/xxxtemp/wiel.h|21|note: candidates are: Wiel Wiel::operator=(Wiel&)|
== Build finished: 5 errors, 2 warnings ===

[/quote]

0

Operator = powinien pobierać stałą referencję (const Wiel&). Popraw jeszcze ten operator() bo może to doprowadzić do dziwnych błędów.

0
Zjarek napisał(a)

Operator = powinien pobierać stałą referencję (const Wiel&)

Zrobione

Zjarek napisał(a)

Popraw jeszcze ten operator() bo może to doprowadzić do dziwnych błędów.

Nie mogę bo nie chodzi mnie o wartość tylko, o dostęp do zmiennej w obiekcie, tak, żebym mógł zapisać coś w obiekcie WIel pod danym adresem. np. ustawić wartość przy potędze x w wielomianie. (coś ala tablica)

Teraz mój wiel.cpp wygląda następująco:

#include "wiel.h"

using namespace std;

Wiel::Wiel ()
{
    n = 0;
    a = NULL;
}

Wiel::Wiel (int x)
{
    if (x<0) throw ("Stopien nie moze byc mniejszy od 0");
    if (x == 0)
    {
        n = 0;
        a = NULL;
    }
    else
    {
        n = x;
        a = new double[n+1];
        for (int i = 0; i<=n; i++) a[i] = 0;
    }
}

Wiel::Wiel (int x, double *tab)
{

    if (x < 0) throw ("Stopien nie moze byc mniejszy od 0");
    if (tab == NULL) throw ("Tablica danych nie moze byc pusta");
    if (x == 0)
    {
        n = 0;
        a = NULL;
    }
    else
    {

        if (x == NULL) cout << " 0 " << endl;
        else
        {
            n = x;
            a = new double[n+1];
            for (int i = 0; i<=n; i++)
                a[i] = tab[i];
        }
    }

}

Wiel::Wiel (const Wiel& w)
{

    n = w.n;
    a = new double[n+1];
    for (int i = 0; i<=n; i++) this->a[i] = w.a[i];

}

Wiel::~Wiel ()
{
    delete []a;
}

ostream& operator<< (ostream& c, Wiel& w)
{
    if (&w == NULL) throw ("Nie ma obiektu");
    if (w.n == 0)
    {
        if (w.a != NULL) cout << w.a[0] << endl; else cout << " 0 " << endl;
    }
    else
    {
        if (w.a == NULL) throw ("Nie moge pobrac danych");
        else
        {
            for (int i = 0; i<w.n; i++)
                cout << w.a[i] << "*x^" << (w.n-i) << " + ";
            cout << w.a[w.n] << "*x^0" << endl;
        }
    }
    return c;
}

Wiel& Wiel::operator= (const Wiel& rhs)
{
    if (this != &rhs){ // w1 = w1 przypisanie nic nie daje
        if (rhs.n == 0)
            {
                if (rhs.a == NULL)
                    {
                        a = NULL;
                        n = 0;
                    }
                    else
                    {
                        n = 0;
                        a = new double[1];
                        a[0] = rhs.a[0];
                    }
            }
            else
            {
                if (a!=NULL) delete[]a;
                n = rhs.n;
                a = new double[rhs.n+1];
                for (int i = 0; i<=rhs.n; i++) a[i] = rhs.a[i];
            }
    }
    return *this;
}

double& Wiel::operator[] (int x)
{
    if (x>n) throw ("Tablica ma mniej elementów");
    if (x<0) throw ("Wskaznik nie moze byc ujemny");
    if (a == NULL) throw ("Nie mam danych do pobrania");
    return a[x];
}

double Wiel::operator() (double x)
{
    if (a == NULL) return 0;
    double val = a[0];
    for (int i = 1; i<=n; i++) val = a[i] + x*val;
    return val;
}

Wiel& Wiel::pochodna ()
{
    Wiel a;
    if (n<0) throw ("Stopien wielomianu nie moze byc mniejszy od 0");
    if (n == 0)
    {
        a.n = 0;
        a.a = NULL;
    }
    else
    {
        a.n = n-1;
        a.a = new double[a.n+1];
        for (int i = 0; i<=a.n; i++)
            a.a[i] = this->a[i]*(n-i);
    }
    //cout << a << endl;
    return a;
}

Wiel Wiel::kanonizuj()
{
    Wiel nowy;
    int st = 0;
    if (a == NULL) throw ("Nie mogę pracować na pustych danych");
    for (int i = 0; i<=n; i++)
        if (a[i] != 0)
            {
                st = n-i;
                break;
            }
    nowy.n = st;
    nowy.a = new double[nowy.n];
    for (int i = 0; i<=nowy.n; i++) nowy.a[i] = this->a[i+st];
    return nowy;
}

W main.cpp
wrzuciłem tylko obsługę błędów: try, catch itd.

Nadal nie działa (działa ale zwraca dziwne wyniki). Kompilator ostrzega, że funkcja pochodna nie powinna zwracać referencji do zmiennej lokalnej (która jest niszczona po wyjściu z funkcji - destruktor), ale powinna zwracać obiekt. Zatem pytanie: jak można pogodzić to, żeby pochodna metoda zwracała obiekt (inaczej się raczej nie da, chyba, że podamy wskaźnik metody?) a operator= przyjmował referencję. Chyba, że, można było to zmienić w operator= na zwykły obiekt?

1 użytkowników online, w tym zalogowanych: 0, gości: 1