Witamy na forum PC Format Zapraszamy do REJESTRACJI


Użytkownicy przeglądający ten wątek: 1 gości

[C++] Wektor nie "zapamięuje" wartości wskaźnika?

#1
[C++] Wektor nie "zapamięuje" wartości wskaźnika?
Witam,
mam kilka klas i struktur:
House, HouseBase, Citizen, City.

Tak mniej więcej wygląda ich budowa:
Kod:
struct House
{
    char owner[32];
    POS beginPos;
    POS endPos;
};

class HouseBase
{
    vector<House*> houses;
public:
    void AddHouse(House house);
    House* GetHouseAt(POS pos);
};

class City
{
    HouseBase houses;
public:
    City() {}
    HouseBase* Houses() { return &houses; }
    void CreateHouse(char* f_owner, POS f_begin, POS f_end);
};

struct Citizen
{
    bool CheckPosition();
    POS cPos;
    City GetCity() { return &city; }
private:
    City city;
}

i definicje do ich metod:
Kod:
void HouseBase::AddHouse(House house)
{
    houses.push_back(&house);
}

House* HouseBase::GetHouseAt(POS Pos) // sprawdzenie, czy ktos w podanej w argumencie pozycji znajduje sie w pozycji ktoregos z domu i zwrocenie wskaznika do tego domu
{
    for(int i = 0; i<houses.size(); i++)
    {
        if(houses[i]->beginPos.x <= Pos.x
        && houses[i]->beginPos.y <= Pos.y
        && houses[i]->endPos.x >= Pos.x
        && houses[i]->endPos.y >= Pos.y)
        {
            return houses[i];
        }
    }

    return NULL;
}

void City::CreateHouse(char* f_owner, POS f_begin, POS f_end)
{
    House h;
    strcpy(h.owner, f_owner);
    h.beginPos = f_begin;
    h.endPos = f_end;
    houses.AddHouse(h);
}

bool Citizen::CheckPosition()
{
    House* h = city->Houses()->GetHouseAt(cPos);
    if(h)
    {
        cout << "the citizen is in " << h->owner << "'s house" << endl;
        return true;
    }
    return false;
}

Załóżmy, że POS to struktura zawierająca zmienne liczbowe: x i y i ma konstuktor, który nadaje im wartości.
Wykonuję taki oto kod:
Kod:
Citizen* c;
c->GetCity()->CreateHouse("test", POS(100, 100), POS(200, 200));
c->cPos = POS(150, 150);
c->CheckPosition();
Jednak nie pokazuje się wiadomość "the citizen is in...".
Spróbowałem sprawdzić zawartość wektora do wskaźnika do struktury House. W pozycjach zapisane były kosmiczne i bezsensowne liczby, a w buforze owner jakieś dziwne znaki.
Co powoduje ten problem?

Wiem, że kod jest być może ciężki do rozczytania i jest go dużo, ale bardzo proszę o pomoc.
 System operacyjny: windows_seven Przeglądarka: firefox
#2
RE: [C++] Wektor nie "zapamięuje" wartości wskaźnika?
Nie wiem czy dobrze rozumiem, ale w:

Kod:
void City::CreateHouse(char* f_owner, POS f_begin, POS f_end

Robisz nową zmienną: House h, ale zapisujesz ją w w wektorze wskaźników, ale przecież po skończeniu metody CreateHouse zmienna ta przestanie istnieć więc wskaźników na nią nie będzie miał już żadnego sensu.

Czemu nie możesz zrobić po prostu wektora z elementami typu House, a nie tak jak teraz z wskaźnikami na nie.


Poza tym Twój kod nawet nie chciał się skompilować w Visualu 2013.


Zmieniłem Twój kod na coś takiego: (działa ale nie wiem czy koncept kodu jest taki jaki byś chciał)

Kod:
#include <vector>
#include <iostream>
#include <conio.h>

using namespace std;

struct POS
{
    int x, y;
};
struct House
{
    char owner[32];
    POS beginPos;
    POS endPos;
};

class HouseBase
{
    vector<House> houses;
public:
    void AddHouse(House house)
    {
            houses.push_back(house);
    }
    House* GetHouseAt(POS pos)
    {
        for (int i = 0; i<houses.size(); i++)
        {
            if (houses[i].beginPos.x <= pos.x
                && houses[i].beginPos.y <= pos.y
                && houses[i].endPos.x >= pos.x
                && houses[i].endPos.y >= pos.y)
            {
                return &houses[i];
            }
        }
        return NULL;


        
    }
};

class City
{
    HouseBase houses;
public:
    City() {}
    HouseBase* Houses() { return &houses; }
    void CreateHouse(char* f_owner, POS f_begin, POS f_end)
    {
        House h;
        strcpy_s(h.owner, f_owner);
        h.beginPos = f_begin;
        h.endPos = f_end;
        houses.AddHouse(h);
    }
};

struct Citizen
{
public:
    City city;
    bool CheckPosition()
    {
        House *h = city.Houses()->GetHouseAt(cPos);
        if (h)
        {
            cout << "the citizen is in " << h->owner << "'s house" << endl;
            return true;
        }
        return false;
    }
    POS cPos;
    City* GetCity() { return &city; }

};

int main()
{
    Citizen c;
    c.GetCity()->CreateHouse("test", POS{ 100, 100 }, POS{ 200, 200 });
    c.cPos = POS{ 100, 100 };
    c.CheckPosition();
    _getch();
    return 0;
}

P.S Mam mało doświadczenia, a nawet bardzo mało w oprogramowaniu obiektowym więc proszę potraktuj ten kod bardziej jako wskazówkę niż gotowe rozwiązane.
 System operacyjny: windows_seven Przeglądarka: firefox
#3
RE: [C++] Wektor nie "zapamięuje" wartości wskaźnika?
Dziękuję za zainteresowanie Wesoły

Zamiast wskaźnika użyłem normalnego i efekt niestety ten sam. Ale i tak użycie go było faktycznie bezsensowne.
Nie wiedziałem, jak przedstawić ten fragment, żeby właśnie pokazać mój koncept (modyfikuję kod innego programu, przez co mój kod jest w pewien sposób w niego "wpleciony"). Tylko, że kodu nie sprawdzałem w kompilatorze.

Zauważyłem, że po zakończeniu funkcji AddNew wielkość wektora się rozszerza i jest zapamiętywana, jednak jego zawartość już nie. Zawartość istnieje tylko przez czas wykonywania funkcji.
Zapomniałem dodać, że kodu, który napisałem tutaj w całości, nie przechowuję w jednym pliku, lecz w wielu.
 System operacyjny: windows_seven Przeglądarka: firefox
#4
RE: [C++] Wektor nie "zapamięuje" wartości wskaźnika?
Pokaż jak to teraz robisz.
 System operacyjny: windows_seven Przeglądarka: firefox
#5
RE: [C++] Wektor nie "zapamięuje" wartości wskaźnika?
https://github.com/kikiw/Teeworlds-Mod/t...ter/city2/
(gra nie jest mojego autorstwa, ja tylko modyfikuję kod)
Kluczowe znaczenie mają pliki:
Cytat:src/game/server/gamecontext.cpp -> linijki od 314 do 319
src/game/server/gamecontext.h -> linijka 47 i 77
src/game/server/houses.h
src/game/server/houses.cpp
src/game/server/entities/character.cpp -> 691 i 692

Zauważyłem też kolejną rzecz: łańcuchy znaków się zapamiętują.
 System operacyjny: windows_seven Przeglądarka: firefox
#6
RE: [C++] Wektor nie "zapamięuje" wartości wskaźnika?
Trudno się połapać, bo trochę tego kodu jest.

Gdybyś mógł dać jakiś minimalistyczny kod gdzie można wytworzyć ten problem to było by łatwiej, ale pewnie przy takim rozbudowaniu projektu nie będzie to łatwe.

Mogę kompletnie źle myśleć, ale:

Metodę GetHouseAt napisać tak:

Kod:
SHouse* SHouseBase::GetHouseAt(vec2 Pos)
{
SHouse* h;
for(int i = 0; i<houses.size(); i++)
{
if(houses[i].beginPos.x <= Pos.x
&& houses[i].beginPos.y <= Pos.y
&& houses[i].endPos.x >= Pos.x
&& houses[i].endPos.y >= Pos.y)
{
h = &houses[i];
return h;
}
}
return NULL;
}


I wywoływać ją tak:

Kod:
switch(GameServer()->Collision()->GetModTile(m_Pos.x, m_Pos.y))
{
case TILE_HOUSE: {
SHouse* house;
house = GameServer()->Houses()->GetHouseAt(m_Pos);
if(house)
{
char buf[64];
str_format(buf, sizeof(buf), "x: %d y: %d", house->beginPos.x, house->beginPos.y);
GameServer()->SendBroadcast(buf, m_pPlayer->GetCID());
}
break; }
}
// handle Weapons
HandleWeapons();
// Previnput
m_PrevInput = m_Input;
return;
}


P.S Tak jak poprzednio, traktuj to bardziej jako wskazówkę bo nie wiem czy dobrze zrozumiałem cały mechanizm patrząc na ten kod, mam nadzieję że coś pomogłem.
 System operacyjny: windows_seven Przeglądarka: firefox
#7
RE: [C++] Wektor nie "zapamięuje" wartości wskaźnika?
Niestety to nic nie da, bo wektor traci zawartość już po zakończeniu funkcji AddNew.

Jednak dziękuję za zainteresowanieOczko
 System operacyjny: windows_seven Przeglądarka: firefox
#8
RE: [C++] Wektor nie "zapamięuje" wartości wskaźnika?
Jak dasz radę to skonstruuj jakiś minimalistyczny kod co spowoduje ten sam błąd, w weekend jeszcze raz zerknę na ten kod dokładniej i jak coś wymyślę to napiszę Ci na PW.
 System operacyjny: windows_seven Przeglądarka: firefox
Programy: Polecane / Nowe / Inne




Podobne wątki ([C++] Wektor nie "zapamięuje" wartości wskaźnika?)
Wątek: Autor Odpowiedzi: Wyświetleń: Ostatni post
  [VBA Excel] Wyszukiwanie wartości w kolumnie Pioro 2 15406 22.06.2020, 18:27
Ostatni post: Pioro
  Przekazywanie wskaźnika przez referencję w Qt Trojan3000 3 23528 10.12.2019, 13:16
Ostatni post: Ajgor
  VisualBasic - tablicowanie wartości funkcji . samanta19 2 10360 20.01.2017, 01:01
Ostatni post: samanta19

Skocz do: