Operator[] a przypisanie

0

Witajcie!
Piszę sobie pewną klasę, w której występują dynamiczne tablice dwuwymiarowe. Wszystko fajnie, tylko, że nie bardzo wiem jak mogę napisać operator indeksowania i przypisania jednocześnie?
chodzi mi o to, abym mógł wykonać coś takiego:

wsk[1][2]=0;

chyba nie mogę skorzystać po prostu z operator[], bo ona przyjmuje tylko jeden argument?
W klasie na razie nic nie ma oprócz konstruktorów i operatora wypisania:

class matrix
{
        double **wsk;
        unsigned int k,w;
        public:
        matrix(unsigned int c, unsigned int j);
        ~matrix();
        void randomize(unsigned int zakres);
        friend ostream& operator<<(ostream&, const matrix&);
};
1
  1. Lepiej zrób to za pomocą operatora (). (Może mieć dowolną ilość argumentów)
  2. Żeby móc modyfikować zwracaj referencję.

C++ FAQ [13.10] How do I create a subscript operator for a Matrix class?

0

Powinien wystarczyć operator[], niech zwróci double* np. return wsk[index];

0
byku_guzio napisał(a)

Powinien wystarczyć operator[], niech zwróci double* np. return wsk[index];

Chyba nie, albo ja coś popitoliłem:
double* matrix::operator[](unsigned int el)
{
return wsk[el];
}
Wywala to segfaulta;

0

To samo z siebie seg'a nie wywali, pokaż jak tego używasz i czy wcześniej alokujesz pamięć dla wsk?

Coś takiego mam na myśli:

class Foo
{
private:
    double **wsk;

public:
    Foo()
    {
        wsk = new double*[10];
        for(int i = 0; i < 10; i++)
        {
            wsk[i] = new double[10];
            for(int j = 0; j < 10; j++)
                wsk[i][j] = i*10+j;
        }
    }

    ~Foo()
    {
        for(int i = 0; i < 10; i++)
            delete [] wsk[i];

        delete [] wsk;
    }

    double* operator[](size_t index)
    {
        return wsk[index];
    }
};

int main ()
{
    Foo f;

    cout << f[2][3] << endl;
    f[2][3] = 25.03;
    cout << f[2][3] << endl;

    return 0;
}
0

Powiem ci, że chyba mamy identycznie, a u mnie mimo to jest coś nie tak :|

class matrix
{
        double **wsk;
        unsigned int k,w;
        double randDouble(double low, double high);
        public:
        matrix(unsigned int c, unsigned int j);
        ~matrix();
        void randomize(unsigned int zakres);
        friend ostream& operator<<(ostream&, const matrix&);
        double* operator[](unsigned int el);
        matrix &operator=(const matrix&);

};

matrix::matrix(unsigned int c, unsigned int j)
{
    wsk=new double*[c];
    for (unsigned int i=0;i<c;i++)
        wsk[i]=new double[j];
    k=c-1;
    w=j-1;
}

matrix::~matrix()
{
    for(unsigned int i=0;i<w;i++)
        delete [] wsk[i];
    delete [] wsk;
}

void matrix::randomize(unsigned int zakres)
{
    srand(time(NULL));
    for(unsigned int i=0;i<=k;i++)
        for(unsigned int j=0;j<=w;j++)
            wsk[i][j]=1.0/(rand()%100);
}

ostream& operator << (ostream& o, const matrix& s)
{
    unsigned int k=s.k;
    unsigned int w=s.w;
    o<<"+";
    for(unsigned int i=0;i<=(k*(PRECISION+2)+8+k);i++)
        o<<"-";
    o<<"+"<<endl;

    o<<setprecision(PRECISION)<<setfill('0')<<fixed;

    for(unsigned int i=0;i<=k;i++)
    {
        o<<"| ";
        for(unsigned int j=0;j<=w;j++)
            o<<s.wsk[i][j]<<" ";
        o<<"|"<<endl;
    }
    o<<"+";
    for(unsigned int i=0;i<=(k*(PRECISION+2)+8+k);i++)
        o<<"-";
    o<<"+";

}

/*matrix &matrix::operator= (const matrix &s)
{
    for(unsigned int i=0;i<k;i++)
        for(unsigned int j=0;j<w;j++)
            wsk[i][j]=s.wsk[i][j];
}*/

double* matrix::operator[](unsigned int el)
{
    return wsk[el];
}

int main()
{
    cout << "Hello world!" << endl;
    matrix a(5,5);
    a.randomize(99);
    cout<<a;
    return 0;
}
0

No nie mamy identycznie. Choćby dlatego, że operatora [] w ogóle nie używasz :p

Nie wiem czym to kompilujesz, ale przykre, że to się Ci skompilowało. Masz błąd w operatorze << przez co dostajesz ten segf zapomniałeś zwrócić wartość, w tym wypadku return o;
Jeżeli dobrze kojarzę to nie zwrócenie wartości z funkcji, która deklaruje, że coś zwraca objawia się undefined behaviour, czyli może się stać cokolwiek.

Jeszcze jedno: masz błąd w destruktorze, zwalniasz o jedną tablicę za mało. W for powinno być i<=w. W ogóle ten pomysł z k i w mniejszymi o jeden od faktycznej ilości elementów jest bez sensu - zmniejsza czytelność, trzeba pamiętać w pętlach, że ma być <=, no i więcej pisania.

0

Tak, faktycznie wysłałem ci wersję "działającą" czyli akurat bez [] ;-) Po prostu zapomniałem dopisać.

Dzięki ci Dobry człowieku za wskazówki :-)
Faktycznie z tym ostream dałem ciała ;-/

Tylko kurczę chyba muszę pogrzebać w ustawieniach IDE Code::Blocks.
Bo coś mi tu nie pasuje. Normalnie jakbym kompilował poza IDE, to g++ wysypałoby ostrzeżenie, o tym, że wychodzę z funkcji nie zwracając niczego.
A kompilując w Code::Blocks nie widzę w ogóle ostrzeżeń. Dziwne. Muszę najwidoczniej gdzieś mieć wyłączone pokazywanie ostrzeżeń

0

przydałby się jeszcze konstruktor kopiujący i operator kopiowania-przypisania. w najprostszym przypadku można ich po prostu zabronić:

private:
    Foo(const Foo&);
    Foo& operator=(const Foo&);
0
Azarien napisał(a)

przydałby się jeszcze konstruktor kopiujący i operator kopiowania-przypisania. w najprostszym przypadku można ich po prostu zabronić:

private:
Foo(const Foo&);
Foo& operator=(const Foo&);

Jakie są konsekwencje nie zabronienia?

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