Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Argument apstraktne metode u c++?

[es] :: C/C++ programiranje :: Argument apstraktne metode u c++?

[ Pregleda: 3969 | Odgovora: 5 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

stevs986
Nikolic Sladjan
Senior Software Developer
Alterset d.o.o
Beograd

Član broj: 121154
Poruke: 140
*.adsl-a-1.sezampro.yu.



+4 Profil

icon Argument apstraktne metode u c++?10.06.2008. u 19:21 - pre 193 meseci
Imam sledeci problem: Imam klasu predmet koja je apstraktna i u njoj metodu xxx koja je takodje apstraktna, iz nje je izvedena klasa Artikal. Metoda xxx mi sluzi za uporedjivanje po nekom kriterijumu atributa iz klase Artikal zato mi je bitno da argument metode xxx bude tipa artikal (pokazivac, referenca). Posto metoda MORA da bude u klasi predmet kako da onda izvedem da njen argument i u klasi Predmet i u klasi Artikal bude tipa artikal. Da li je to uopste izvodljivo....???
 
Odgovor na temu

glorius
Damir Nikolic
C++ developer
SR

Član broj: 4366
Poruke: 428
212.200.238.*

ICQ: 208550327


+14 Profil

icon Re: Argument apstraktne metode u c++?11.06.2008. u 08:52 - pre 193 meseci
Klasa Predmet mora da bude svesna postojanja klase Artikal.

Sve uradi kako si planirao samo ces morati pre klase Predmet da deklarises klasu Artikal ( nacin na koji si ti razmisljao ). Znaci:

Code:


// Predmet header file
// ...

class Artikal;

class Predmet
{
   //...
   void Funkcija(Artikal * pArt);
}



Postoji mali problem sa ovim pristupom. Bolje resenje je da Funkcija prihvata argument Predmet i da se interno downcast-uje u Artikal...

Evo prvo kako bi to izgledalo kada bi argument bio Artikal:

Code:


#include <iostream>

class Artikal;

class Predmet
{
public:
    virtual void Funkcija(Artikal * pArtikal) = 0;
};

class Artikal : public Predmet
{
public:
    Artikal() { id = 3; }
    void Funkcija(Artikal * pArtikal);

    int id;
};

void Artikal::Funkcija(Artikal * pArtikal)
{
    std::cout << pArtikal->id;
}

int _tmain(int argc, _TCHAR* argv[])
{
    Predmet * pArt1 = new Artikal;
    Predmet * pArt2 = new Artikal;

    pArt2->Funkcija((Artikal*)pArt2);
    return 0;
}



pArt2 se mora downcast-ovati i to mora uciniti korinik tvoje klase za razliku od sledeceg primera gde se implementacija downcast-ovanja sakriva u nasoj funkciji:

Code:


#include <iostream>

class Predmet
{
public:
    virtual void Funkcija(Predmet * pPredmet) = 0;
};

class Artikal : public Predmet
{
public:
    Artikal() { id = 3; }
    void Funkcija(Predmet * pPredmet);

    int id;
};

void Artikal::Funkcija(Predmet * pPredmet)
{
    std::cout << ((Artikal*)pPredmet)->id;
}

int _tmain(int argc, _TCHAR* argv[])
{
    Predmet * pArt1 = new Artikal;
    Predmet * pArt2 = new Artikal;

    pArt2->Funkcija(pArt2);
    return 0;
}



Primecujes da sada Predmet ne zna nista o Artiklu ( njega to i ne zanima ) i zbog toga smo izbacili 'class Artikal' deo koda...
Nasa funkcija prihvata Predmet jer je i Artikal predmet ( u tvom dizajnu ).
Implementacija krije sta se zapravo zbiva tako da kod u main-u radi onako kako bi korisnik i ocekivao da koristi ove 2 klase.

Ako ti ovo nije bas najjasnije, pogledaj malo nasledjivanje, virtuelne funkcije i apstraktne klase :)
EOF
 
Odgovor na temu

stevs986
Nikolic Sladjan
Senior Software Developer
Alterset d.o.o
Beograd

Član broj: 121154
Poruke: 140
*.adsl-1.sezampro.yu.



+4 Profil

icon Re: Argument apstraktne metode u c++?11.06.2008. u 11:14 - pre 193 meseci
Mnogo ti hvala, bas si mi lepo objasnio, jednostavno za razumevanje..... Pronasao sam i ja slicno resenje sa static_cast i proradilo mi je... :) TO je u stvari isto kao sto si i ti radio sa kastovanjem samo sto sam ja koristio static_cast, znas li mozda u cemu je razlika (izmedju kastovanja sa static_cast i samo koriscenja zagrada ispred kao sto si ti radio) ako uopste postoji...
 
Odgovor na temu

Goran Arandjelovic
Beograd

Član broj: 29116
Poruke: 387
*.dynamic.sbb.rs.



+9 Profil

icon Re: Argument apstraktne metode u c++?11.06.2008. u 15:16 - pre 193 meseci
Nema neke posebne razlike, sem sto je static_cast "vidljiviji".. i ne moze da menja konstantnost objekta dok obicno C kastovanje moze.

Uoci razliku

Code:

struct C
{
  C() {x = 11;}
  int x;
};

...
const C x;
C *y = (C*)(&x);

y->x = 100; // uspevas da promenis x.x
...


Code:

const C x;
int *y = static_cast<C*>(&x); //ovo se ne kompajlira!
// obavestava te da pokusavas da uklonis "konstantnost"

y->x = 100;


Za skidanje konstantnosti sluzi const_cast.

Ono sto tebi mahom treba je dynamic_cast, jer ce on koristiti RTTI informacije za kastovanje tvojih objekata, a u tvom primeru koristi static_cast SAMO kada si siguran je ispod onaj objekat u koji hoces da downcastujes pokazivac/referencu.

Ako downcastujes sa dynamic_cast, koristice se RTTI informacije i ako je lose castovanje rezultujuci pokazivac bice NULL. U slucaju da su u pitanju reference, desice se izuzetak bad_cast.
 
Odgovor na temu

glorius
Damir Nikolic
C++ developer
SR

Član broj: 4366
Poruke: 428
212.200.238.*

ICQ: 208550327


+14 Profil

icon Re: Argument apstraktne metode u c++?11.06.2008. u 15:37 - pre 193 meseci
Ovde postoji lepo objasnjenje cast-ovanja u C++:

http://www.cplusplus.com/doc/tutorial/typecasting.html


EOF
 
Odgovor na temu

Goran Arandjelovic
Beograd

Član broj: 29116
Poruke: 387
*.dynamic.sbb.rs.



+9 Profil

icon Re: Argument apstraktne metode u c++?11.06.2008. u 15:58 - pre 193 meseci
E da, jos jedna stvar... ovde bi moglo zapravo da postoji jos elegantije resenje:

Recimo:

Code:

class Predmet
{
  virtual void f(wrap<Predmet> w) = 0; // dole pise sta je 'wrap'
};

class Artikal : public Predmet
{
  virtual void f(wrap<Predmet> w)
  {
     wrap<Artikal> a = w;
     a->ispisi_Artikal();
  };

  void ispisi_Artikal() {...}
};


Evo sta je wrap...ovo je napisano na brzinu, treba tu doraditi jos dosta toga, ali je odlican primer za ilustraciju :-)

Code:

#include <iostream>
using namespace std;

class A
{
    public:
    virtual void f(){}
};

class C : public A
{
    public:
    virtual void f(){}
};

template<typename T>
class wrap
{
    public:
    wrap(T *ptr){x = ptr;}
    template<typename U>
    wrap(wrap<U> const &y)
    {
        T *tmp;
        if(tmp = dynamic_cast<T*>(y.x)){
        x = tmp;
        }else{
        // ups!
        }
    }

        ~wrap() { delete x; }

        // i ovde jos postoji overloadovan operator ->, ali me je mrzelo da pisem.

    T *x;
};

int main()
{
    wrap<A> ptr(new C);
    
    wrap<C> ptr1 = ptr;
}


Naravno, klasi wrap fale i ostali konstruktori...x treba da bude private..itd. Ovo je samo primer.
 
Odgovor na temu

[es] :: C/C++ programiranje :: Argument apstraktne metode u c++?

[ Pregleda: 3969 | Odgovora: 5 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.