Zugriff auf Arrays als Datenmember einer Klasse



  • Hi,
    genauso wie du nicht sowas machen kannst:

    int zahlen[3];
      zahlen = { 3,4,6 };
    

    Kannst du auch nicht dein Vorhaben in die Tat setzen.

    Das Problem könntest du lösen in dem du dir ein Array definierst und dann in dein dirname die daten rüberkopierst mit copy.

    Oder du benutzt vector<TString> statt TString[x]

    Edit: Da man geht zwischendurch kurz in die Küche und landet direkt auf Platz 3. Na immerhin ist CStoll nicht erster ...



  • KasF schrieb:

    Na immerhin ist CStoll nicht erster ...

    Ich trag's mit Fassung 😃 (im Gegensatz zu manch anderem ist es mir egal, der wievielte ich bin ;))



  • CStoll schrieb:

    KasF schrieb:

    Na immerhin ist CStoll nicht erster ...

    Ich trag's mit Fassung 😃 (im Gegensatz zu manch anderem ist es mir egal, der wievielte ich bin ;))

    Das kannst Du auch, weil Du eh fast immer der Erste bist 😉



  • CStoll schrieb:

    KasF schrieb:

    Na immerhin ist CStoll nicht erster ...

    Ich trag's mit Fassung 😃 (im Gegensatz zu manch anderem ist es mir egal, der wievielte ich bin ;))

    War ja nicht ernst gemeint 😉



  • Paddy82 schrieb:

    Das kannst Du auch, weil Du eh fast immer der Erste bist 😉

    Und wenn schon 😃 (manche Leute scheinen sich echt ein Kreuz in den Kalendar zu setzen, wenn sie schneller waren als ich - warum eigentlich? 😕)



  • Vielleicht unverschämt und bissl off-topic. Aber wie geht das, dass du immer morgends hier bist und immer jeden sofort antworten kannst. Entweder du hast viel Freizeit in deinen Job oder du bist ein Schüler der nur schwänzt 😃

    Hat mich immer schonmal irgendwie interessiert ...



  • Tja, das würdest du gerne wissen 🙂 (nur so viel: ich bin kein Schüler mehr)



  • CStoll ist Hartz 4 Empfenger.



  • CStoll ist bestimmt der Chef 😃



  • LordJaxom schrieb:

    CStoll ist bestimmt der Chef 😃

    Das wird's sein 😃

    PS: Könnte vielleicht einer der C++ Mods den Off-Teil herausschneiden und ins NadrW verschieben?



  • Danke erstmal fuer die prompten Antworten 🙂

    CStoll schrieb:

    Oder du lässt den Ctor der Klasse weg und initialisierst sie komplett über Initialisierungsliste:

    SampleInfo<4> data = {
      {"/files/directory1/","/files/directory2/","/files/directory3/","/files/directory4/"},
      {"", "", "", ""},
      {158, 66, 60, 23},
      {".00p.root", ".99p.root", ".99e.root", ".98e.root"}
    };
    

    (das klappt (afaik) allerdings nur, wenn die Klasse keinen selbstgeschriebenen Konstruktor hat)

    hm. ohne Ctor, also auch ohne Dtor? dann koennte ich gleich n Struct draus machen, oder?

    Fahrscheinlinch werd ich am Ende doch die Alternative nehmen und ne "echte" Klasse mit dynamischer Speicherverwaltung machen wo ich dann den Kram a la

    SampleInfo data;
    
    data.add("/files/directory1/", "", 158, ".00p.root");
    data.add("/files/directory2/", "", 66, ".99p.root");
    //etc
    

    reinhaue. Ist zwar mehr Aufwand beim coden, sieht aber imho sauberer aus 😉



  • pumuckl schrieb:

    Danke erstmal fuer die prompten Antworten 🙂

    CStoll schrieb:

    Oder du lässt den Ctor der Klasse weg und initialisierst sie komplett über Initialisierungsliste:

    SampleInfo<4> data = {
      {"/files/directory1/","/files/directory2/","/files/directory3/","/files/directory4/"},
      {"", "", "", ""},
      {158, 66, 60, 23},
      {".00p.root", ".99p.root", ".99e.root", ".98e.root"}
    };
    

    (das klappt (afaik) allerdings nur, wenn die Klasse keinen selbstgeschriebenen Konstruktor hat)

    hm. ohne Ctor, also auch ohne Dtor? dann koennte ich gleich n Struct draus machen, oder?

    Der Dtor stört in diesem Zusammenhang nicht wirklich. Aber da er in deinem Fall leer ist, kannst du ihn auf jeden Fall weglassen.

    Fahrscheinlinch werd ich am Ende doch die Alternative nehmen und ne "echte" Klasse mit dynamischer Speicherverwaltung machen wo ich dann den Kram a la

    SampleInfo data;
    
    data.add("/files/directory1/", "", 158, ".00p.root");
    data.add("/files/directory2/", "", 66, ".99p.root");
    //etc
    

    reinhaue. Ist zwar mehr Aufwand beim coden, sieht aber imho sauberer aus 😉

    Besser ist das 😉 (wobei, ich würde eine Hilfsklasse 'entry' für einen Datensatz erstellen und dann die Speicherverwaltung einem vector<entry> überlassen)



  • Du kannst dir einen Initproxy schreiben.

    template <class T, class I>
    class InitProxy
    {
    public:
    	typedef typename T value_type;
    	typedef typename I iterator;
    
    	InitProxy(iterator iterator_, int count_) :
    		m_Iterator(iterator_),
    		m_iCount(count_)
    	{}
    
    	~InitProxy()
    	{}
    
    	inline InitProxy<T, I>& operator, (value_type const& value_)
    	{
    		if ( m_iCount == 0 )
    			EXCEPTION_THROW("Zu viele Argumente");
    
    		--m_iCount;
    		++m_Iterator;
    		*m_Iterator = value_;
    
    		return *this;
    	}
    protected:
    	iterator m_Iterator;
    	int m_iCount;
    };
    

    Dann überlädst du in deiner Arrayzuweisungsklasse den operator=

    template <class T>
    class MyVector
    {
    public:
    	typedef T value_type;
    	typedef vector<value_type>::iterator iterator;
    
    	MyVector(int size_) ....
      .
      .
      .
    
    	InitProxy<value_type, iterator> operator= (value_type const& value_)
    	{
    		m_DataArray[0] = value_;
    		return InitProxy<value_type, iterator>(m_DataArray.begin(), static_cast<int>(m_DataArray.size()-1));
    	}
    
    protected:
    	vector<value_type> m_DataArray;
    };
    

    danach kann ein Objekt der Klasse einfach mit Werten gefüllt werden:

    MyVector<int> v(3);
    
    	v = 3, 455, 26;
    


  • CStoll schrieb:

    [

    Fahrscheinlinch werd ich am Ende doch die Alternative nehmen und ne "echte" Klasse mit dynamischer Speicherverwaltung machen wo ich dann den Kram a la

    SampleInfo data;
    
    data.add("/files/directory1/", "", 158, ".00p.root");
    data.add("/files/directory2/", "", 66, ".99p.root");
    //etc
    

    reinhaue. Ist zwar mehr Aufwand beim coden, sieht aber imho sauberer aus 😉

    Besser ist das 😉 (wobei, ich würde eine Hilfsklasse 'entry' für einen Datensatz erstellen und dann die Speicherverwaltung einem vector<entry> überlassen)

    Jein. Natuerlich waere das besser, wenn ich nicht an anderer Stelle Zugriff auf die Arrys der einzelnen Bestandteile eines jeden Eintrags braeuchte (also z.B. diNames aus meinem ersten Beitrag). Dafuer muesste ich sonst jeden entry im vektor auseinanderpfluecken, mir ein neues Array bauen usw.

    Ich habs jetzt wie folgt bewaeltigt:

    class TFileSample
    {
    protected:
      Int_t nDir_;
      TString* dirNames_;
      TString* fPrefixes_;
      TString* fSuffixes_;
      Int_t* nFiles_;
      Int_t* minFNrs_;
    
    public:
      // default Constructor
      TFileSample() 
        : nDir_(0), dirNames_(0), fPrefixes_(0), 
          fSuffixes_(0), nFiles_(0), minFNrs_(0)
      {};
        // destructor
      ~TFileSample()
      { 
        delete[] dirNames_;
        delete[] fPrefixes_;
        delete[] fSuffixes_;
        delete[] nFiles_;
        delete[] minFNrs_;
      };
    
      void add(TString dirName, TString fPrefix, Int_t nFiles,
    	   TString fSuffix, Int_t minFNr = 1)
        {
          //allocate memory for larger arrays
          TString* dnTemp = new TString[nDir_+1]; 
          // [..] and so on
          // copy old arrays into new allocated memory
          for (Int_t i=0; i<nDir_; i++)
            {
              dnTemp[i] = dirNames_[i];
              // [..] and so on
            }
          // append new Data
          dnTemp[nDir_] = dirName;
          // [..] and so on
          //delete old arrays and set pointers to new arrays
          delete[] dirNames_;
          dirNames_ = dnTemp;
          // [..] and so on
          return;
        };
    
      const TString* getDirNames() const
        {return dirNames_;};
      const TString* getFilePrefixes() const
        {return fPrefixes_;};
      const Int_t* getNFiles() const
        {return nFiles_;};
      const TString* getFileSuffixes() const
        {return fSuffixes_;};
      const Int_t* getMinFNr() const
        {return minFNrs_;};
      Int_t getNDir() const
        {return nDir_;};
    
    };
    

    Das komische kommt jetzt erst:

    TFileSample mydata;
    
    mydata.add("/files/directory1/" //line 12
    	 ,"",158,".00p.root");
    

    liefert mir wieder einen Error:
    Config_UE.h:12: error: syntax error before `.' token

    😮
    keinen Plan was das soll... wenn ichs als Zeiger *mydata und mit mydata->add() mache kommt syntax error before `->' token 😕



  • Pumuckl (offline) schrieb:

    CStoll schrieb:

    [

    Fahrscheinlinch werd ich am Ende doch die Alternative nehmen und ne "echte" Klasse mit dynamischer Speicherverwaltung machen wo ich dann den Kram a la

    SampleInfo data;
    
    data.add("/files/directory1/", "", 158, ".00p.root");
    data.add("/files/directory2/", "", 66, ".99p.root");
    //etc
    

    reinhaue. Ist zwar mehr Aufwand beim coden, sieht aber imho sauberer aus 😉

    Besser ist das 😉 (wobei, ich würde eine Hilfsklasse 'entry' für einen Datensatz erstellen und dann die Speicherverwaltung einem vector<entry> überlassen)

    Jein. Natuerlich waere das besser, wenn ich nicht an anderer Stelle Zugriff auf die Arrys der einzelnen Bestandteile eines jeden Eintrags braeuchte (also z.B. diNames aus meinem ersten Beitrag). Dafuer muesste ich sonst jeden entry im vektor auseinanderpfluecken, mir ein neues Array bauen usw.

    OK, das ist ein Argument, das ich nachvollziehen kann (obwohl ich mir auch vorstellen könnte, zur Lösung die "andere Stelle" so umzubauen, daß sie selber aus einem vector<entry> die richtigen Teile raussucht). Aber dann nimm wenigstens vector<>en zur Verwaltung deiner Einzelarrays - damit ersparst du dir eine Menge Arbeit (und vector::push_back() ist auch wesentlich effizienter als dein Lösungsansatz ;)).

    Das komische kommt jetzt erst:

    TFileSample mydata;
    
    mydata.add("/files/directory1/" //line 12
    	 ,"",158,".00p.root");
    

    liefert mir wieder einen Error:
    Config_UE.h:12: error: syntax error before `.' token

    Ich hoffe mal, das da steht im inneren einer Funktion. "mydata.add(...);" ist eine Anweisung - und die darf nicht frei im Raum schweben.



  • Leider kann ich an der "anderen Stelle" nicht viel rumfuhrwerken. Da hat jemand anderes die Verantwortung und der hat leider mehr mit Teilchenphysik als mit Objektorientiertem C++ am Hut. Sprich: ich bin gezwungen, ihm völlig oldscool einen Zeiger auf den Anfang und einen int mit der Länge des Arrays zu übergeben 😕


Anmelden zum Antworten