Operator funkcyjny indeksu tablicy

0

Mam taką klasę, która zawiera w sobie tabelę punktów.
Chciałbym, żeby elementy tej tabeli można było wywoływać takim zapisem:

ObiektMojejKlasy[0].x = 1;
ObiektMojejKlasy[6].y = 81;
struct Point{ int x,y; };

class MojaKlasa
{
    public:
    int* tabela;
    int length;
    MojaKlasa (int len) 
    {
        length = len;
        tabela (int*) malloc(sizeof(Point)*len+sizeof(int));
        tabela* = length;
    }
    
    Point* operator[] (int index)
    {
       if (index >= Length )
       {
           std::cout<<"Error: index "<<index<<" is out of range!\n";
           Point P(-1,-1);
           Point* pP;
           pP = &P;
           return pP;
       }
       Point* pP;
       pP = (Point*)(tabela + 2*index);
       return pP;
    }
};

Zrobiłem już jedną funkcję operatorową, ale zapis przy jej użyciu wygląda inaczej niż tego potrzebuje:

MojaKlasa MK(10);
(*newCopy[0]).x = 99;
(*newCopy[1]).y = 65;

dodanie znacznika <code class="cpp"> - fp

0
struct Point{ int x,y; };
 
class MojaKlasa
{
public:
    Point* tabela;
    int length;

    MojaKlasa (int len) 
    {
        length = len;
        tabela = new Point[len];
    }

    ~MojaKlasa() 
    {
        delete [] tabela;
    }
 
    Point& operator[] (int index)
    {
       if (index >= length)
       {
           std::cout<<"Error: index "<<index<<" is out of range!\n";
           Point P(-1,-1);
           return P;
       }
       return tabela[index];
    }
};
0

Jeśli nie piszesz własnej implementacji wektora, użyj klasy std::vector zamiast się babrać z nagimi new/delete i wynikającymi z tego memleakami.

0

@lukasz1235

Twoja tabela jest o 4 bajty mniejsza od mojej, na początku przed tablicą punktów jest komórka typu integer zawierająca długosć tabeli. Dlatego nie użyłem operatora new.

Sorry ,w moim kodzie wkradł się błąd, zamiast:

pP = (Point*)(tabela + 2*index); 

powinno być:

pP = (Point*)(tabela + 2*index + 1); 
kq napisał(a):

Jeśli nie piszesz własnej implementacji wektora, użyj klasy std::vector zamiast się babrać z nagimi new/delete i wynikającymi z tego memleakami.

Nie wiem czy można to nazwać implementacją wektora,ale tak piszę własną klasę, która tak powinna wyglądać. Jedyne co chce zmienić to funkcję operatorową.

0
Artur237 napisał(a):

Twoja tabela jest o 4 bajty mniejsza od mojej, na początku przed tablicą punktów jest komórka typu integer zawierająca długosć tabeli.
Tylko po co, skoro masz już pole length przechowujące długość tablicy?

0
lukasz1235 napisał(a):
Artur237 napisał(a):

Twoja tabela jest o 4 bajty mniejsza od mojej, na początku przed tablicą punktów jest komórka typu integer zawierająca długosć tabeli.
Tylko po co, skoro masz już pole length przechowujące długość tablicy?

Własnie tak ma być.

0
Artur237 napisał(a):

Nie wiem czy można to nazwać implementacją wektora,ale tak piszę własną klasę, która tak powinna wyglądać. Jedyne co chce zmienić to funkcję operatorową.

Ok, w takim razie pamiętaj o zasadzie trzech (a teraz już pięciu).

Wyżej masz poprawną implementację - zwracaj referencję do elementu zamiast wskaźnika:

    Point& operator[] (int index)
    {
       if (index >= Length )    
       {
          // throw może?
       }

       return *(Point*)(tabela + 2*index);
    }

Przy okazji, takie użycie pamięci zwróconej przez malloc może być bardzo zdradliwe - w tym przypadku najprawdopodobniej będzie ok, ale gdybyś zmienił int na double do określenia punktu to najpewniej byś rzutował niepoprawnie zalignowaną pamięć na Point, a to już jest UB. Masz osobne pole length - dlaczego je duplikujesz?

0
 return *(Point*)(tabela + 2*index);

Dzięki, o to chodziło.

Co do zdublowanego length, dllka ma współpracować z programem napisanym w Pascalu, w którym tablice wyglądają inaczej niż w c - przed pierwszym elementem tablicy jest komórka zawierająca jej długosć. Nie będę eksportował do programu całej klasy tylko wskaźnik na pierwszy element tablicy (tabelka+1). Więc jedno length jest dla Pascala,a drugie dla wygody w mojej klasie.

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