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

Savet - inicijalizacija atributa

[es] :: C/C++ programiranje :: Savet - inicijalizacija atributa

[ Pregleda: 4057 | Odgovora: 15 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Zevs85
Zeljko Todorovic
Novi Sad, Sabac

Član broj: 24612
Poruke: 325
212.200.139.*



+21 Profil

icon Savet - inicijalizacija atributa22.08.2009. u 14:04 - pre 177 meseci
Pozdrav,

interesuje me koji je najbolji nacin resiti sledeci problem.
Imam klasu sa npr 3 atributa, ime, prezime, jmbg. Imam XML datoteku ciji elementi se isto tako zovu.
<korisnik>
<ime> Korsink </ime>
<prezime> Prezime </prezime>
<jmbg> 1234434 </jmbg>
</korisnik>

Sad mi treba najlaksi nacin da inicijalizujem atribute klase...
Uvek mogu napraviti nesto tipa
if (element == "ime") objekat.ime = ime
else if....

Ali mislim da to nije pravo resenje.

Jel postoji u C++ mogucnost da kazem da atribut sa "imenom" dobije "vrednost"... Ili tako nekako.. ??
 
Odgovor na temu

Goran Arandjelovic
Beograd

Član broj: 29116
Poruke: 387
*.telenor.co.yu.



+9 Profil

icon Re: Savet - inicijalizacija atributa22.08.2009. u 16:12 - pre 177 meseci
Je l' ti bilo kakvo menjanje izgenerisanih klasa odgovara ili njih nebi hteo da diraš?
 
Odgovor na temu

Mihajlo Cvetanović
Beograd

Moderator
Član broj: 37636
Poruke: 1249



+96 Profil

icon Re: Savet - inicijalizacija atributa23.08.2009. u 18:46 - pre 177 meseci
Ne vredi razmišljati mnogo o takvim stvarima. Ako imaš tri članice klase, onda je if-else-if najefikasnije rešenje, pod uslovom da se to if-else-if ne ponavlja na deset mesta. Možeš eventualno umesto tri članice da koristiš map<string, string>, ali slutim da nema nikakve potrebe za tim. Kad bi bilo stotinak članica klase onda bi imalo smisla razmišljati o nekom elegantnijem rešenju.
 
Odgovor na temu

Zevs85
Zeljko Todorovic
Novi Sad, Sabac

Član broj: 24612
Poruke: 325
212.200.139.*



+21 Profil

icon Re: Savet - inicijalizacija atributa24.08.2009. u 07:55 - pre 177 meseci
Citat:
Goran Arandjelovic: Je l' ti bilo kakvo menjanje izgenerisanih klasa odgovara ili njih nebi hteo da diraš?

Mogu da menjam klase.
Citat:
Mihajlo Cvetanović: ...Kad bi bilo stotinak članica klase onda bi imalo smisla razmišljati o nekom elegantnijem rešenju.

E bas o tome se radi :)

Znam da u C#-u i Javi postoji mogucnost dobijanja informacija o atributima, metodama i tako to, dalo bi se uraditi... Ali za C++ bas ne znam da li je to moguce i kako...
 
Odgovor na temu

Mihajlo Cvetanović
Beograd

Moderator
Član broj: 37636
Poruke: 1249



+96 Profil

icon Re: Savet - inicijalizacija atributa24.08.2009. u 10:29 - pre 177 meseci
Prvo što mi pada na pamet je da umesto 100 članica klase imaš jednu članicu koja je map<string, string>.

Druga opcija nije za ljude sa pejsmejkerom:

Code:

#include <map>
#include <string>
using namespace std;

class Klasa {
public:
  string jedan, dva, tri;
  static map<string, string Klasa::*> mapa;
}

map<string, string Klasa::*> Klasa::mapa;

main() {
  // mapa je staticka, ova inicijalizacija se radi samo jednom
  Klasa::mapa["jedan"] = &Klasa::jedan;
  Klasa::mapa["dva"]   = &Klasa::dva;
  Klasa::mapa["tri"]   = &Klasa::tri;

  Klasa objekat;
  objekat.*Klasa::mapa["jedan"] = "vrednost jedan";
  objekat.*Klasa::mapa["dva"] = "druga vrednost";
  objekat.*Klasa::mapa["tri"] = "nesto trece";
}
 
Odgovor na temu

Goran Arandjelovic
Beograd

Član broj: 29116
Poruke: 387
62.108.108.*



+9 Profil

icon Re: Savet - inicijalizacija atributa24.08.2009. u 17:27 - pre 177 meseci
@Mihajlo
S tim sto nigde nije pomenuo da su svi atributi istog tipa, vec verovatno i ne moraju da budu.

--

Evo jedne ideje:

Code:

#include <string>
#include <iostream>
using namespace std;

class izgenerisana_klasa
{
  public:
    /* konstruktori/destruktor i ostale metode */
    template<typename T>
    void set_attr(string attr_name, T value)
    {
      if(attr_name == "jedan"){
        jedan = value;
      }else if(attr_name == "dva"){
        dva = value;
      }else if(attr_name == "tri"){
        tri = value;
      }else if(attr_name == "cetiri"){
        cetiri = value;
      }
    }
  private:
    int jedan;
    string dva;
    float tri;
    int cetiri;
};

int main()
{
  izgenerisana_klasa Test; // ako postoji default konstruktor
  
  Test.set_attr("jedan", 5);
  Test.set_attr("dva", "neka vrednost");
  Test.set_attr("cetiri, 15);
  Test.set_attr("tri", 5.14); // mada bi mogao da prodje i int

  // ili... umesto if(element == "ime")...

  Test.set_attr(element, val); // gde je val vrednost koja odgovara tom elementu

  return(0);
}


Ovo gore nisam testirao, ali bi trebalo da je ok. Naravno, imam i neku ideju za mnogo krace resenje (koje cak verovatno nebi ni zahtevalo izmenu generisanih klasa, ali je malo bolesno...)

Edit: @Mihajlo, na koju si drugu opciju mislio ako nije tajna?

[Ovu poruku je menjao Goran Arandjelovic dana 24.08.2009. u 19:12 GMT+1]
 
Odgovor na temu

Mihajlo Cvetanović
Beograd

Moderator
Član broj: 37636
Poruke: 1249



+96 Profil

icon Re: Savet - inicijalizacija atributa25.08.2009. u 09:25 - pre 177 meseci
Ni ja nisam testirao, ali cenim da ovo ne može da se kompajlira. Ako instanciraš set_attr sa T kao int onda će ti kompajler javiti grešku u liniji "dva = value;" da nema operator= koji prima int. Ako instanciraš sa T kao string onda je greška u liniji "jedan = value;" jer kompajler ne zna kako da konvertuje string u int.
 
Odgovor na temu

1jedini
Dejan Milosavljevic
BG

Član broj: 102721
Poruke: 74
*.static.sbb.rs.



Profil

icon Re: Savet - inicijalizacija atributa25.08.2009. u 11:59 - pre 177 meseci
Kombinuj explicitnu specijalizaciju sa resenjem koje je dao Mihajlo Cvetanović.
AKA DDMM
 
Odgovor na temu

Goran Arandjelovic
Beograd

Član broj: 29116
Poruke: 387
*.rcub.bg.ac.rs.



+9 Profil

icon Re: Savet - inicijalizacija atributa25.08.2009. u 15:34 - pre 177 meseci
@Mihajlo
Da, dobro si primetio. Greška. Ali evo sada TESTIRANOG rešenja koje koristi nešto slično statičkom IF-u:

Code:

#include <string>
#include <iostream>
using namespace std;

template<typename T, typename U>
struct SET_F
{
  static void set(T &arg1, U &arg2)
  {
  }
};

template<typename T>
struct SET_F<T, T>
{
  static void set(T &arg1, T &arg2)
  {
    arg1 = arg2;
  }
};

struct SET
{
  template<typename T, typename U>
  SET(T &attr, U &value)
  {
       SET_F<T, U>::set(attr, value);
  }
};

class izgenerisana_klasa
{
  public:
    /* konstruktori/destruktor i ostale metode */
    template<typename T>
    void set_attr(string attr_name, T value)
    {
      if(attr_name == "jedan"){
        SET i(jedan, value);
      }else if(attr_name == "dva"){
        SET i(dva, value);
      }else if(attr_name == "tri"){
        SET i(tri, value);
      }else if(attr_name == "cetiri"){
        SET i(cetiri, value);
      }
    }
  
  private:
    int jedan;
    string dva;
    float tri;
    int cetiri;
};

int main()
{
  izgenerisana_klasa Test; // ako postoji default konstruktor
  
  Test.set_attr("jedan", 5);
  Test.set_attr("dva", string("neka vrednost"));
  Test.set_attr("cetiri", 15);
  Test.set_attr("tri", 5.14f);

  // ili... umesto if(element == "ime")...

  // Test.set_attr(element, val); // gde je val vrednost koja odgovara tom elementu

  return(0);
}


Naravno, moguće je dodati potrebne specijalizacije da se dopusti float -> double, const char* -> string i slične stvari. Ovo radi za identične tipove.
 
Odgovor na temu

Mihajlo Cvetanović
Beograd

Moderator
Član broj: 37636
Poruke: 1249



+96 Profil

icon Re: Savet - inicijalizacija atributa25.08.2009. u 15:55 - pre 177 meseci
Mislim da je kod malo neefikasan, jer imaš template funkciju set_attr koja će se instancirati onoliko puta koliko ima različitih tipova, ali u svakoj of tih funkcija ispitivaće se i oni attr_name koji nisu datog tipa. Drugi detalj je što mi se čini da su input vrednosti za naš algoritam uvek stringovi, a algoritam je taj koji treba da uradi konverziju u odgovarajući tip na osnovu imena atributa. A možda ne treba da komplikujemo, možda je string jedini tip. Početni poster treba da kaže šta mu treba.

Nego da se vratimo početnom problemu. Šta ako imaš stotinu (ili hiljadu) atributa, a ne samo četiri? Da li i onda da koristimo if-else-if kobasicu?
 
Odgovor na temu

Goran Arandjelovic
Beograd

Član broj: 29116
Poruke: 387
77.46.235.*



+9 Profil

icon Re: Savet - inicijalizacija atributa25.08.2009. u 17:41 - pre 177 meseci
To što ima nepotrebnih ispitivanja, to bi moglo da se reši bez problema. Ako su input-i isključivo stringovi, onda ja nisam dobro razumeo, mislio sam da je input uređeni par (string ime, T vrednost), gde je T baš odgovarajući tip, a ne string.

Ali u pravu si, neka čovek kaže tačno kakav mu je input, nije baš bio najprecizniji tako da sam ja obradio generalan slučaj.
 
Odgovor na temu

Eurora3D Team
Nebojsa - Programer & Vodja tima
Beograd

Član broj: 120376
Poruke: 900
*.dynamic.sbb.rs.



+7 Profil

icon Re: Savet - inicijalizacija atributa26.08.2009. u 00:41 - pre 177 meseci
Mozes ovako nesto ...
Broj podataka nije ogranicen ali jeste vrsta ... ali to moze lako da se prevazidje dodavajem funkcija itd.
Podatci se inicijalizuju prvim upisom,
Nisam mnogo razradjivao ali bi trebalo da je to to sto si trazio.
Code:

//
#include <iostream>
#include <string>
#include <vector>
using namespace std;

//prouci i
//#include <typeinfo>
// cout << "a is: " << typeid(a).name() << '\n';

//prva klasa
class DataClass
{
public:
    string value_name;

    DataClass():type(0){}
    inline bool SetValue(string s_value_name, int value){if(!type) {type = 1; value_name = s_value_name;} if(type == 1) {Int = value;return true;} return false;}
    inline bool SetValue(string s_value_name, float value){if(!type) {type = 2; value_name = s_value_name;} if(type == 2) {Float = value; return true;} return false;}
    inline bool SetValue(string s_value_name, string value){if(!type){type = 3; value_name = s_value_name;} if(type == 3) {String = value;return true;} return false;}
    inline bool GetValue(string s_value_name,int& i){if(type == 1) {i = Int;return true;} return false;}
    inline bool GetValue(string s_value_name,float& f){if(type == 2) {f = Float;return true;} return false;}
    inline bool GetValue(string s_value_name,string& s){if(type == 3) {s = String;return true;} return false;}

private:
    int type;
    int Int;
    float Float;
    string String;
};

typedef vector<DataClass*> DC; // definisanje vektora tipa DataClass

//druga klasa
class DataContainer
{
public:
    //set
    void SetValue(string value_name, int value)
    {
        bool n = false;
        DataClass* dc = GetData(value_name);
        if(!dc)
        {
            dc = new DataClass();
            n = true;
        }
        if(!dc)
            return;
        if(n && dc->SetValue(value_name,value))
            data_list.push_back(dc);
    }
    void SetValue(string value_name, float value)
    {
        bool n = false;
        DataClass* dc = GetData(value_name);
        if(!dc)
        {
            dc = new DataClass();
            n = true;
        }
        if(!dc)
            return;
        if(n && dc->SetValue(value_name,value))
            data_list.push_back(dc);
    }
    void SetValue(string value_name, string value)
    {
        bool n = false;
        DataClass* dc = GetData(value_name);
        if(!dc)
        {
            dc = new DataClass();
            n = true;
        }
        if(!dc)
            return;
        if(n && dc->SetValue(value_name,value))
            data_list.push_back(dc);
    }
    //get
    bool GetValue(string value_name, int& value)
    {
        DataClass* dc = GetData(value_name);
        if(!dc)
            return false;
        return dc->GetValue(value_name,value);
    }
    bool GetValue(string value_name, float& value)
    {
        DataClass* dc = GetData(value_name);
        if(!dc)
            return false;
        return dc->GetValue(value_name,value);
    }
    bool GetValue(string value_name, string& value)
    {
        DataClass* dc = GetData(value_name);
        if(!dc)
            return false;
        return dc->GetValue(value_name,value);
    }
    
private:
    DataClass* GetData(string value_name)
    {
        
        if(!data_list.empty())
        {
            DataClass* dc = 0;
            DC::iterator Iterator;
            for (Iterator = data_list.begin(); Iterator != data_list.end();Iterator++)
            {
                dc = *Iterator;
                if(dc->value_name == value_name)
                    return dc;
            }
        }
        return (DataClass*) 0;
    }

    DC data_list; // vektor tipa DataClass
};

DataContainer Memory;

int main () 
{
    int i1,i2;
    Memory.SetValue("int_jedan", 1);
    Memory.SetValue("int_dva", 2);

    Memory.GetValue("int_dva", i2);
    Memory.GetValue("int_jedan", i1);

    float f1=1.0f, f2=2.0f;

    Memory.SetValue("float_jedan", f1);
    Memory.SetValue("float_dva", f2);

    //zamenili smo mesta
    Memory.GetValue("float_jedan", f2);
    Memory.GetValue("float_dva", f1);

    string s1, s2 = "s2 string";

    Memory.SetValue("string_jedan", s2);
    Memory.SetValue("string_dva", "s1 string");

    Memory.GetValue("string_jedan", s2);
    Memory.GetValue("string_dva", s1);

    cout << "int_jedan " << i1 << endl;
    cout << "int_dva " << i2 << endl;

    cout << "float_jedan " << f1 << endl;
    cout << "float_dva " << f2 << endl;

    cout << "string_jedan " << s1 << endl;
    cout << "string_dva " << s2 << endl;
    
    return 0;
}


[Ovu poruku je menjao Eurora3D Team dana 26.08.2009. u 01:52 GMT+1]
 
Odgovor na temu

Mihajlo Cvetanović
Beograd

Moderator
Član broj: 37636
Poruke: 1249



+96 Profil

icon Re: Savet - inicijalizacija atributa26.08.2009. u 09:53 - pre 177 meseci
Ovde bi mogao da se ubaci i jedan union, greota da se rasipa memorija. Uzgred, if-else-if (teoretsku) kobasicu i direktan pristup članicama klase si zamenio iteracijom liste u for-if petlji. Taj deo koda je sad manji, ali je neefikasniji i što se tiče upisa i što se tiče čitanja. Kod upisa moramo da prođemo kroz celu listu da bismo shvatili da dati atribut ne postoji. Kod čitanja nemamo više direktan pristup nego opet moramo da iteriramo po listi.
 
Odgovor na temu

Eurora3D Team
Nebojsa - Programer & Vodja tima
Beograd

Član broj: 120376
Poruke: 900
*.dynamic.sbb.rs.



+7 Profil

icon Re: Savet - inicijalizacija atributa26.08.2009. u 12:43 - pre 177 meseci
Da greota :) (ti si iz c++ kao i ja, ovi iz NETa bacaju MB a ne bytove) , ali koliko sam shvatio najvise ce da koristi string tako da se rasipa ~ (sizeof(int) + sizeof(float)) * broj podataka ...
A i nije neki sampion u brzini ... to mi je prvo palo na pamet.
U svakom slucaju resenje je fleksibilno i moze lako da ga sredi i neko ko nema mnogo iskustva , tako da kome treba eto mu neki pocetak
...
Da najvaznije
U ovu klasu moze da se lako ubaci 1000 raznih podataka na jednostavan nacin ... normalno mogu i da se procitaju


[Ovu poruku je menjao Eurora3D Team dana 26.08.2009. u 14:24 GMT+1]
 
Odgovor na temu

Eurora3D Team
Nebojsa - Programer & Vodja tima
Beograd

Član broj: 120376
Poruke: 900
*.dynamic.sbb.rs.



+7 Profil

icon Re: Savet - inicijalizacija atributa26.08.2009. u 17:48 - pre 177 meseci
Da dodam , ovim nacinima kako ste vi probali nije moguce u klasu dodati hiljede atibuta kojima unapred ne znamo imena ... tako da je ovo trece resenje jedino koje moze da resi ovaj problem. Ja sam ogranicio ono sto znamo , tipove podataka.
Ako neko ima bolju ideju neka napise ... poz
 
Odgovor na temu

kiklop74
Darko Miletić
Buenos Aires

Član broj: 78422
Poruke: 569
200.49.157.*

Sajt: ar.linkedin.com/pub/darko..


+13 Profil

icon Re: Savet - inicijalizacija atributa27.08.2009. u 13:48 - pre 177 meseci
Meni se cini da bi koriscenje boost::any sa std::map bilo adekvatno resenje.

http://www.boost.org/doc/libs/1_39_0/doc/html/any.html

Tko leti vrijedi
 
Odgovor na temu

[es] :: C/C++ programiranje :: Savet - inicijalizacija atributa

[ Pregleda: 4057 | Odgovora: 15 ] > FB > Twit

Postavi temu Odgovori

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