Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Problem z dynamic_cast i iteratorem

Ostatnio zmodyfikowano 2015-01-14 14:10
Autor Wiadomość
Sarth
Temat założony przez niniejszego użytkownika
Problem z dynamic_cast i iteratorem
» 2015-01-13 23:02:20
Witam. Mam problem z poniższym kodem, ciągle wyrzuca mi błędy. Problem leży w linijce z instrukcją if. clientList miał być listą przechowującą wskaźniki na obiekty pochodne od klasy client (klasa wirtualna, dziedziczą od niej klasy t.j. person, firm, service itd.), natomiast poniższa funkcja miała wypisywać wszystkie obiekty będące obiektami klasy person. Nie mam już żadnych pomysłów jak poradzić sobie z tym błędem.

C/C++
int main()
{
   
    list < client *> clientList;
    client * per = new person( 100, "a", "b", 100 );
    clientList.push_back( per );
   
    delete[] per;
   
    return 0;
}

Funkcja z klasy person:
C/C++
void person::print( list < client *> lista )
{ //dodac wyjatek ze lista jest pusta
    // list<person*> l;
    //l = dynamic_cast<person*>(lista);
    list < client *>::iterator iter;
   
    list < person *> * per;
   
    for( iter = lista.begin(); iter != lista.end(); iter++ )
    {
        list < person *> * i;
        i =& iter;
        if( per = dynamic_cast < list < person *>::iterator >( i ) ) //*iter też nie działało
        //{
       
             std::cout << "Numer karty stalego klienta: " <<( * iter )->loyaltyCard;
        // std::cout<<"Imie: "<<(*iter)->firstName;
        //std::cout<<"Nazwisko: "<<(*iter)->lastName;
        //std::cout<<"Pesel: "<<(*iter)->pesel;
        //}
    }
}
P-124855
pekfos
» 2015-01-13 23:10:45
C/C++
client * per = new person( 100, "a", "b", 100 );
clientList.push_back( per );

delete[] per;
Nie możesz tak usunąć jednego obiektu.
P-124857
Sarth
Temat założony przez niniejszego użytkownika
» 2015-01-13 23:14:14
Faktycznie głupi błąd, ale to nie w tym jest problem.
P-124860
pekfos
» 2015-01-13 23:50:50
ciągle wyrzuca mi błędy.
Może by tak coś więcej..?
P-124865
Sarth
Temat założony przez niniejszego użytkownika
» 2015-01-14 09:14:10
C/C++
//client.h
#ifndef client_h
#define client_h
#include <iostream>

using namespace std;

class client
{
public:
    int loyaltyCard;
    virtual void print() = 0;
    virtual void search() = 0;
    client( int lc );
   
};

#endif

C/C++
//client.cpp
#include "client.h"

client::client( int lc )
    : loyaltyCard( lc )
{
   
}

C/C++
//person.h
#ifndef person_h
#define person_h
#include <iostream>
#include <string>
#include <list>
#include "client.h"

class person
    : public client
{
    std::string firstName;
    std::string lastName;
    int pesel;
   
public:
    person( int lc, std::string fn, std::string ln, int p );
    void print( list < client *> lista );
   
};

#endif

C/C++
//person.h
#include "client.h"
#include "person.h"

using namespace std;

person::person( int lc, std::string fn, std::string ln, int p )
    : client( lc )
     , firstName( fn )
     , lastName( ln )
     , pesel( p )
{
   
}

void person::print( list < client *> lista )
{ //dodac wyjatek ze lista jest pusta
    // list<person*> l;
    //l = dynamic_cast<person*>(lista);
    list < client *>::iterator iter;
   
    list < person *> * per;
   
    for( iter = lista.begin(); iter != lista.end(); iter++ )
    {
        list < person *> * i;
        i =& iter;
        if( per = dynamic_cast < list < person *>::iterator >( i ) )
        //{
       
             std::cout << "Numer karty stalego klienta: " <<( * iter )->loyaltyCard;
        // std::cout<<"Imie: "<<(*iter)->firstName;
        //std::cout<<"Nazwisko: "<<(*iter).lastName;
        //std::cout<<"Pesel: "<<(*iter).pesel;
        //}
    }
}

Ta zmienna "i" to nie jest potrzebna, ale kombinowałem na różne sposoby, a teraz wrzuciłem kod, który teraz mam.

Mam jeszcze inne klasy, dosyć podobne, ale uboższe - prawie nic w nich nie ma.
P-124870
Monika90
» 2015-01-14 10:40:43

for (auto a_client : lista)
    if (auto a_person = dynamic_cast<person*>(a_client))
    {
        std::cout << "Imie: " << a_person->firstName;
    }


A tak w ogóle, to klasa client musi mieć wirtualny destruktor, klasa person jest abstrakcyjna - nie da się tworzyć obiektów tej klasy. Masz też using namespace std; w pliku nagłówkowym.
P-124877
Sarth
Temat założony przez niniejszego użytkownika
» 2015-01-14 13:02:48
1. Jak z klasy client (na razie) usunę deklarację metody czysto wirtualnej
virtual void search() = 0;
 i dodam destruktor wirtualny to klasa client stanie się abstrakcyjna, a klasa person przestanie taka być (ewentualnie jak w klasie person napiszę funkcję search) i będę mógł tworzyć od niej obiekty. Dobrze myślę?
2. Czy
auto
 w podany powyżej sposób może być używane tylko w c++11/14? Jeżeli tak to chciałbym też wiedzieć co powinienem zrobić, gdy nie mogę używać c++11.
3. Nie za bardzo rozumiem tę konstrukcję
auto a_client: lista
, można prosić o wyjaśnienie, albo link gdzie mógłbym o tym poczytać (może być po angielsku)? https://pl.wikipedia.org/wiki​/C%2B%2B11#Automatyczne_okre.C5.9Blenie_typu To chyba nie to?

using namespace::std staram się nie używać, poprawię to. Dodam, że nie chcę tworzyć obiektów klasy client, tylko person itd. (czy od klas pochodnych od client). Poza tym dziękuję za dotychczasowe odpowiedzi.
P-124890
Monika90
» 2015-01-14 13:15:45
1.
ewentualnie jak w klasie person napiszę funkcję search) i będę mógł tworzyć od niej obiekty.
print też musisz napisać

2. Tak, auto i taka postać pętli for jest dostępna od C++11

3. http://en.cppreference.com/w/cpp/language/range-for


W przestarzałej wersji języka to będzie tak
C/C++
for( iter = lista.begin(); iter != lista.end(); iter++ )
{
    if( person * per = dynamic_cast < person *>( * iter ) )
    {
       
        std::cout << "Imie: " << per->firstName;
    }
}
P-124892
« 1 » 2
  Strona 1 z 2 Następna strona