Dlaczego dwa obiekty wskazują na to samo miejsce w pamięci

0

Cześć, stworzyłem sobie metodę:

CTable CTable::operator=(CTable& b)
{
    if (lengthArray != b.lengthArray)
    {
        changeLengthArray(b.lengthArray);
    }
    for (int i = 0; i < lengthArray; i++)
    {
        pointer[i] = b.pointer[i];
    }
    s_name = b.s_name;
    return *this;
}

a po wykonaniu instrukcji

 a = b;

wszystko jest w porządku, wartości z obiektu b są przepisane do wartości obiektu a. Problem polega na tym, że po wykonaniu tej metody zarówno a jak i b wskazują na to samo miejsce w pamięci. Jeśli teraz zmienię wartości w obiekcie b, to jednocześnie zmieniam je w obiekcie a. Może ktoś wskazać mi gdzie robię błąd?

0

Bez definicji CTable ciężko powiedzieć. Zapewne s_name jest wskaźnikiem lub pointer tablicą wskaźników, a ty je bezwiednie kopiujesz.

Obowiązkowa lektura: rule of zero

0
class CTable
{
    private:
        const int defaultLengthArray = 5;
        const std::string defaultName = "text";
        int lengthArray;
        std::string s_name;
        int* pointer;
    public:
        CTable();
        CTable(string SName);
        CTable(CTable &pcOther); 
0

Pokaż ten kod, który dowodzi tego co twierdzisz (że obiekty wskazują na to samo miejsce w pamięci i że zmiana w jednym powoduje zmianę w drugim).

0
twonek napisał(a):

Pokaż ten kod, który dowodzi tego co twierdzisz (że obiekty wskazują na to samo miejsce w pamięci i że zmiana w jednym powoduje zmianę w drugim).

Nie wiem o który kod pytasz, mam metodę która wpisuje wartość do tablicy w obiekcie, oraz metodę która wyświetla informację o obiekcie. Chodzi Ci o którąś z tych metod?

0

Kod wygląda ok, poza tym, że zwracasz kopię zamiast referencji z operatora =.

0

@twonek wnioskuję to po tym, iż tworzę sobie dwa obiekty A i B, wpisuję do obiektu A wartości do tablicy. Kiedy wykonam instrukcję B = A; wartości z A są też w obiekcie B. Ale jeśli teraz zmienię długość tablicy B, długość tablicy A też się zmienia, jeśli zmienię nazwę obiektu B, nazwa obiektu A też się zmienia. Stąd ten wniosek.

PS. proszę moda o skasowanie poprzedniego posta.

0

Zmiana długości:

int* CTable::copyAndIncreaseArray (int* oldArray, int newLength)
    {
        int* wsk = new int[newLength];
        for (int i=0; i<lengthArray; i++)
        {
            wsk[i] = oldArray[i];
        }
        lengthArray = newLength;
        return wsk;
    }


void CTable::changeLengthArray(int newLength)
    {
        int* tempPointer = copyAndIncreaseArray(pointer, newLength);
        delete[] pointer;
        pointer = tempPointer;
        cout << "Dlugosc tablicy: " << lengthArray << endl;
    } 

ZMIANA NAZWY:

void CTable::vSetName(string SName)
    {
        s_name = SName;
    } 

WSTAWIENIE WARTOŚCI DO TABLICY

 
void CTable::setValueToArray(int index, int value)
    {
        if ((index < lengthArray) && (index > -1))
        {
            pointer[index] = value;
        }
    }

INFORMACJE O OBIEKCIE:

string CTable::getObjectInfo()
{
    string temp = "<";
    temp += s_name + "> length: <" + to_stringS(lengthArray) + "> values: <";
    for (int i=0; i<lengthArray; i++)
    {
        temp += to_stringS(getPointer(i));
        temp += ", ";
    }
    return temp + ">";
} 
0

Ale jeśli teraz zmienię długość tablicy B, długość tablicy A też się zmienia, jeśli zmienię nazwę obiektu B, nazwa obiektu A też się zmienia.
Gdzie jest kod, który TO robi? Gdzie widzisz, że nazwa obiekt A się zmienia?

0

Chyba o to Ci chodzi :)

Obiekty przechowywane są w vectorze:

 vector<CTable*> contener;

Jest interfejs użytkownika, i switchem wybieram co ma być zrobione:

 
case CHANGE_THE_LENGHT_OF_THE_ARRAY:
                {
                    if (create)
                    {
                        cout << "W ktorym obiekcie chcesz zmienic dlugosc tablicy?: ";
                        numberObj = write();
                        if ((numberObj > 0) && numberObj <= contener.size())
                        {
                            cout << "Podaj dlugosc tablicy: ";
                            lenArr = write();
                            if (lenArr > 0)
                            {
                                contener[numberObj-1]->changeLengthArray(lenArr);
                            }
                            else
                            {
                                cout << "Liczba musi byc dodatnia";
                            }
                        }
                        else
                        {
                            cout << "Liczba wychodzi poza zakres";
                        }
                        }
                    else
                    {
                        cout << "Stworz obiekty!";
                    }
                } break;


case NEW_NAME_OBJECT:
                {
                    if (create)
                    {
                        cout << "Nazwe ktorego objektu chcesz zmienic?";
                        numberObj = write();
                        if ((numberObj > 0) && numberObj <= contener.size())
                        {
                            cout << "Podaj nazwe: ";
                            std::cin >> newName;
                            contener[numberObj-1]->vSetName(newName);
                        }
                        else
                        {
                            cout << "Wyszedles poza zakres!";
                        }
                    }
                    else
                    {
                        cout << "Stworz obiekty!";
                    }
                } break;


case INFO_OBJECT:
                {
                    if (create)
                    {
                        cout << "Informacje o ktorym obiekcie chcesz zobaczyc?";
                        numberObj = write();
                        if ((numberObj > 0) && numberObj <= contener.size())
                        {
                            cout << contener[numberObj-1]->getObjectInfo();

                        }
                        else
                        {
                            cout << "Wyszedles poza zakres";
                        }
                    }
                    else
                    {
                        cout << "Stworz najpierw obiekty!";
                    }
                } break;

            case WRITE_VALUE_TO_CELL:
                {
                    if (create)
                    {
                        cout << "Ktory obiekt? ";
                        numberObj = write();
                        if ((numberObj > 0) && numberObj <= contener.size())
                        {
                            cout << "Ktora komorka? ";
                            cell = write();
                            if ((cell > 0) && cell <= contener[numberObj-1]->getLengthArray())
                            {
                                cout << "Podaj wartosc do komorki";
                                value = write();
                                contener[numberObj-1]->setValueToArray(cell-1,value);
                            }
                            else
                            {
                                cout << "Wyszedles poza zakres!";
                            }
                        }
                        else
                        {
                            cout << "Wyszedles poza zakres";
                        }
                    }
                    else
                    {
                        cout << "Stworz obiekty!";
                    }
                } break;


case OPERATORS:
                {
                    if (create)
                    {
                        cout << "Wybierz dzialanie: " << endl << "1. a = b + c" << endl << "2. a = b - c" << endl
                            << "3. a = b * c" << endl << "4. a = b";
                        choice = write();
                        if (choice > -1 && choice < 4)
                        {
                            do
                            {
                                cout << "Podaj pierwsze obiekt (a)";
                                a = write();
                            } while (!a>0 && !a<contener.size());
                            do
                            {
                                cout << "Podaj drugi obiekt (b)";
                                b = write();
                            } while (!b>0 && !b<contener.size() && b!=a);
                            do
                            {
                                cout << "Podaj trzeci obiekt (c)";
                                c = write();
                            } while (!c>0 && !c<contener.size() && c!=b);
                        }
                        else
                            if (choice == 4)
                            {
                                do
                                {
                                    cout << "Podaj pierwsze obiekt (a)";
                                    a = write();
                                } while (!a>0 && !a<contener.size());
                                do
                                {
                                    cout << "Podaj drugi obiekt (b)";
                                    b = write();
                                } while (!b>0 && !b<contener.size() && b!=a);
                            }
                            else
                            {
                                cout << "Nie ma takiego dzialania!";
                            }
                            switch(choice)
                            {
                            case ADD:
                                {
                                }break;

                            case SUB:
                                {
                                }break;

                            case MULTTI:
                                {
                                }break;

                            case EQUALS:
                                {
                                    contener[a-1]=contener[b-1];
                                }break;
                            }
                    }
                    else
                    {
                        cout << "Stworz najpierw obiekty!";
                    }
                }
            }
1

Poczytaj o wskaźnikach.
Przecież w wektorze trzymasz wskaźniki a nie obiekty, więc jak zrobisz np.

contener[0] = contener[1]

to oczywiste jest, że będą wskazywać na ten sam obiekt.

0

PRAWDA! Wielkie dzięki! Czyli w zasadzie to tak powinien działać przeciążony operator =, prawda?
Obj1 = Obj2 powinno przypisać adres Obj2 do Obj1.

1

Nie nie nie. Przecież w tej chwili masz właśnie przypisanie wskaźników i zamiast 2 osobnych obiektów masz 2 wskaźniki do tego samego obiektu.
Twój operator= nawet nie został wywołany, bo to było przypisanie wskaźników a nie obiektów typu CTable.
Wektor powinien trzymać obiekty.

0

Czyli powinno być coś w stylu
contener[0]* = contener[1]* tak?
W sensie wartość wskaźnika contener[0] przypisz wartości wskaźnika contener[1].

1

Powinno być

vector<CTable> contener

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