Kompozycja w klasie z polimorfizmem

0

Cześć. Natrafiłem na taki problem otóż w metodzie klasy start

void Start::Add(Person *one) {
	Vector.push_back(one);
}
 

chce dodać polimorficznie, sprzedawce, który jest dzieckiem klasy person. O ile wszystko gra w przykładzie u góry, to w momencie, gdy chce zamienić klasę start w kompozycję, tzn chce przechowywać wskaźniki do kopi sprzedawców, które sam stworzę w klasie start, trafiam w mur,
nie mogę użyć new bo gdy:

void Start::Add(Person *one) {
	Vector.push_back(new Person(&(*newone));
}
 

To kompilator zwraca błąd, że person to nie sprzedawca, więc nie używa on tutaj rzutowania, jak w pierwszym przyapdku.
Ma ktoś pomysł jak to rozwiązać. Bardzo dziękuję za pomoc. Pozdro

1

Jak już musisz kopiować, zrób w interfejsie metodę clone.

Przy okazji, nie używaj nagich wskaźników, to antyidiom w nowoczesnym kodzie C++. Masz std::unique_ptr, std::shared_ptr lub nawet boost::ptr_vector.

0

Jeżeli sprzedawca nie jest osobą, to o jakim polimorfizmie tutaj mówimy? Chcesz dodać sprzedawcę to niech funkcja przyjmuje sprzedawcę.

2

@B_jak_boa bo to co chcesz zrobić nie ma sensu. Niech sprzedawca umie sie klonować i tyle. Chociaż mam wątpliwosci czy takie kopiowanie to dobra opcja, bo wyczuwam spore wycieki pamieci ;]

0

Bardzo dziękuję za pomoc, ale nie do końca o to mi chodzi, już znalazłem, rozwiązanie ale brzydko wygląda. Otóż takie coś działa:

 Start Zbior;
                 Zbior.Add(new Sprzedawca(Jan));
                 Zbior.Add(new Wyjec(Morda));

Metoda z klasy start, została ta pierwsza, od której zacząłem. Moje pytanie brzmi, jak zrobić, żeby te new zadziałało, w środku tej metody,
chce osiągnąć, ten sam efekt. Bardzo dziękuję, za wszelkie uwagi.

0

Możesz uczynić add szablonem.

template<typename T>
void Add(T* ptr){
	Vector.push_back(new T(*ptr));
}

To powinno działać (jeśli funkcja ta będzie poprawnie wywoływana dla dynamicznego typu obiektu), ale takie coś zdecydowanie lepiej załatwić z użyciem clone.

void Add(Person* ptr){
	Vector.push_back(ptr->clone());
}

No i wciąż nie powinieneś używać nagich wskaźników w taki sposób.

0

Rozumiem, bardzo dziękuję. Na razie robie tylko obrys, potem dodam te lepsze wskaźniki, bo muszę się dokładnie zapoznać jeszcze z tą bliblioteką. Niestety, próbowałem już wcześniej tego szablonu, i o ile moim sposobem, program uruchamia poprawnie destruktory, przez szablon, traci dostęp do całej klasy sprzedawcy, bo kilka innych klas, jest kumulowanych w inny sposób niż sprzedawca, i one dalej są poprawnie destruktowane.

0

W takim razie pokaż więcej kodu, założyłem, że Zbior.Add(new Sprzedawca(Jan)); woła void Start::Add(Person *one), zdefiniowane w pierwszym poście. W tym momencie to nie ma prawa inaczej działać.

Wskaźników nie zostawiaj na później bo będziesz miał mnóstwo syfu w kodzie i Ci się nie będzie chciało tego robić.

0
kq napisał(a):

W takim razie pokaż więcej kodu, założyłem, że Zbior.Add(new Sprzedawca(Jan)); woła void Start::Add(Person *one), zdefiniowane w pierwszym poście. W tym momencie to nie ma prawa inaczej działać.

Wskaźników nie zostawiaj na później bo będziesz miał mnóstwo syfu w kodzie i Ci się nie będzie chciało tego robić.

No bo woła, dla mnie to też nie logiczne, że tak działa, a tak nie. Tak mnie to skonfundowało, że na dziś już dość.
Kod łącznie z przykładem innej klasy:

 
Start Start1;
Start1.Add("Kamil"); 
Sprzedawca Jan;
Start1.Add(new Sprzedawca(Jan));
//Twoj Sposob
//Start1.Add(&Jan);

Teraz metody:

 
~Start() {for (vector<Person*>::iterator it = Vector.begin(), end_it = Vector.end(); it != end_it; ++it) delete *it;
		Vector.clear();}
void Start::Add(string name) { 
		Vector.push_back( new Klient(name)); 
}
void Start::Add(Person *one) {
//Vector.push_back(new Person(*one));
}

Tym szablonem, nie włącza w ogóle destruktora dla Jana, jak zrobie po mojemu, wszystko śmiga. Sam widze, że to samo. Jeszcze raz dzięki

0

Przepraszam tam nastąpił błąd, w ostatniej metodzie.

void Start::Add(Person *one) {
Vector.push_back(one);
//Twoj sposob
Vector.push_back(new Person(*one));
}

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