Działania na wektorze w klasie

0

Cześć, mam problem z napisaniem klasy agregującej. Prawdopodobnie robię coś źle z wektorem, ale zupełnie nie mam pomysłu co. Problem jest z wyświetlaniem zawartości wektora w funkcji Act(). Jeśli zawartość tej funkcji wrzucę do funkcji InitZoo() to wszystko poprawnie działa, więc prawdopodobnie źle zapisuję dane do wektora Animals. Z góry dziękuję za pomoc

#pragma once
#include "vector"
#include "iostream"
#include <ctime>
#include <windows.h>
#include <conio.h>

using namespace std;

class TAnimal;
typedef std::vector<TAnimal*> AnimalVectType;

typedef enum { ctCalm = 1, ctUnrest } ConditionType;

//--------------------------------------------------------------------------------------
// TAnimal
//--------------------------------------------------------------------------------------

//klasa TZoo poprzez wektor animal agreguje dowolną liczbę obiektów TAnimal

class TZoo
{
public:
    AnimalVectType Animals;
    void Zoo();
    void InitZoo();
    void Act(ConditionType pCondition);

};
void TZoo::InitZoo()
{
    TDog d1;
    d1.set_name("Piesel");
    TLion l1, l2;
    l1.set_name("Lew");
    l2.set_name("Lewel");
    TSheep s1;
    s1.set_name("Owcel");
    Animals.push_back(&d1);
    Animals.push_back(&l1);
    Animals.push_back(&l2);
    Animals.push_back(&s1);

}

void TZoo::Act(ConditionType pCondition)
{

    if (pCondition == ctCalm)
    {
        for (auto it = Animals.begin(); it != Animals.end(); it++)
        {
            (*it)->MakeSound();
        }
        //cout << "hejka1";
    }
    else if (pCondition == ctUnrest)
    {
        //for (auto it = Animals.begin(); it != Animals.end(); it++)
        //{
        //  (*it)->MakeSoundLoud();
        //}
        cout << "hejka2";
    }
}
1
Kabak napisał(a):

Cześć, mam problem z napisaniem klasy agregującej. Prawdopodobnie robię coś źle z wektorem, ale zupełnie nie mam pomysłu co. Problem jest z wyświetlaniem zawartości wektora w funkcji Act(). Jeśli zawartość tej funkcji wrzucę do funkcji InitZoo() to wszystko poprawnie działa, więc prawdopodobnie źle zapisuję dane do wektora Animals. Z góry dziękuję za pomoc

class TAnimal;
typedef std::vector<TAnimal*> AnimalVectType;

To jest wektor wskaźników (adresów).
Ustawiasz je w funkcji ze zmiennych lokalnych, po czym w/w przestają istnieć, elementy wektora wskazują w próżnie.
To byłby dobry (mniej zły) wektor do zwierząt alokowanych.
BTW ustawianie imienia O WILE ŁADNIEJ by było w konstruktorze.

zoo.push_back( new Dog("Burek") );
2
void TZoo::InitZoo()
{
    TDog d1;
    d1.set_name("Piesel");
    TLion l1, l2;
    l1.set_name("Lew");
    l2.set_name("Lewel");
    TSheep s1;
    s1.set_name("Owcel");
    Animals.push_back(&d1);
    Animals.push_back(&l1);
    Animals.push_back(&l2);
    Animals.push_back(&s1);

}

Dodajesz wskaźniki do zmiennych lokalnych. Te zmienne przestają istnieć po wyjściu z funkcji. Prawdopodobnie chcesz mieć wektor unique_ptr na swoje zwierzaki (z polimorficznym destruktorem).

1

Możesz też stworzyć w klasie TAnimal konstruktor sparametryzowany, który przyjmuje jako argument nazwę zwierzęcia i w liście inicjalizacyjnej go inicjalizuje, np:

TAnimal(std::string animalName = ""): *TwojaNazwaPola*(animalName) {}

i wówczas będziesz mógł sobie elegancko wrzucać do vectora:

void TZoo::InitZoo()
{
    Animals.push_back(new TDog("Piesel"));
    Animals.push_back(new TLion("Lew"));
    Animals.push_back(new TLion("Lewel"));
    Animals.push_back(new TSheep("Owcel"));
}

i wyeliminujesz problem.

Edit:
oczywiście o wiele lepiej jest użyć unique_ptr niż czyste wskaźniki, ale tutaj dopasowałem do czystych wskaźników.

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