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