[solved] Array dynamischer Größe in struct + Verwendung als const



  • Hallo,

    irgendwie stehe ich gerade auf dem Schlauch. Ich möchte mir gerne ein struct anlegen, welches ein dynamisches Array beinhaltet. Mit diesem struct will ich dann einige Konstanten definieren.

    Mein Ansatz (der nicht funktioniert):

    struct t_filter
    {
    /// \brief Default constructor.
    t_filter() : data(NULL), size(0) {}
    
    /// \brief Destructor.
    ~t_filter() { if( data != NULL ) { delete [] data; data = NULL; } }
    
    double*      data;  ///< Store data here.
    unsigned int size;  ///< Length of data array.
    };
    
    const t_filter FILTER_1 = { {1.0,2.0,1.0}, 3 }; // Das ist Quatsch!
    

    Vielleicht könnte mir gerade jemand auf die Sprünge helfen, wie ich das am besten mache?

    Viele Grüße,
    mbu



  • mbu schrieb:

    Vielleicht könnte mir gerade jemand auf die Sprünge helfen, wie ich das am besten mache?

    Mit C++ Mitteln:

    #include <vector>
    
    struct t_filter
    {
        std::vector<unsigned int> data;
    };
    
    int main()
    {
        t_filter a;
        a.push_back(1.0);
        a.push_back(2.0);
        a.push_back(1.0);
    }
    


  • Jau, das wär natürlich super. Allerdings möchte ich ja einige konstante Filter definieren. Wie lässt sich das denn mit C++-Mitteln (also std::vector) realisieren? Und wenn es sich nicht realisieren lässt, wie mache ich es dann mit C-Mitteln?



  • mbu schrieb:

    Allerdings möchte ich ja einige konstante Filter definieren.

    Wie wäre es wenn du erst einmal in etwa Beschreibst was du eigentlich vor hast. dynamisch und konstant sind ja an sich auch schon ein Widerspruch, und wenn du die t_filter-Objekte selbst Konstant machst kann man den Vektor auch nicht ändern.

    Beispielsweise:

    void tueWas(t_filter const & filter)
    {
        // filter.push_back(2.0); <-- Geht nicht, da konstant
    }
    


  • Ich habe bis jetzt einige Filter unterschiedlicher Länge als Konstanten definiert:

    const double COEFF_DAUBECHIES7[7] =
      {
        -0.09127176311424948,
        -0.05754352622849957,
         0.5912717631142470,
         1.115087052456994,
         0.5912717631142470,
        -0.05754352622849957,
        -0.09127176311424948
      };
    
      const double COEFF_DAUBECHIES9[9] =
      {
         0.02674875741080976,
        -0.01686411844287495,
        -0.07822326652898785,
         0.2668641184428723,
         0.6029490182363579,
         0.2668641184428723,
        -0.07822326652898785,
        -0.01686411844287495,
         0.02674875741080976
      };
    

    Benutzt habe ich diese bis jetzt über einen enum:

    /// \brief Enumerates all possible filter types.
      enum t_interpolation
      {
        IP_DAUBECHIES7,  ///< Daubechies 7-tap wavelet filter.
        IP_DAUBECHIES9,  ///< Daubechies 9-tap wavelet filter.
        IP_GAUSS,        ///< Gauss filter.
        IP_GAUSS3,       ///< Gauss 3-tap filter.
        IP_LEGALL5       ///< Le-Gall 5-tap wavelet filter.
      };
    

    indem ich entsprechende Funktionen mit einem Parameter für t_interpolation aufgerufen habe:

    void convolve_horizontal(vnl_matrix<int>& img, const t_interpolation ip_type);
    

    Nun muss ich aber in der oben deklarierten Funktion abhängig von ip_type den Code dynamisch anpassen. Das möchte ich natürlich insofern vermeiden, dass der Aufruf mit jedem möglichen Filtertypen funktioniert. Nichtsdestotrotz möchte ich weiterhin einige konstant vordefinierte Filter haben.

    Zur Erklärung konstant/dynamisch: Die Filter haben alle unterschiedliche Länge (also eigentlich nicht dynamisch, stimmt) aber sollen konstant vordefiniert sein.

    Ich möchte also eigentlich die oben zitierte Definition der Konstanten beibehalten, allerdings soll noch die Länge des Arrays verfügbar sein. Dafür benötige ich ja dann ein struct.



  • Schreib doch noch ein konstantes Array das als Typ Pointer auf double-Arrays hat. Dann kannst du über diesen Array, bei dem du als Index deine Enum-Elemente nehmen kannst, auf das dazugehörige konstante Array zugreifen. Dann brauchst du deiner Funktion auch nur den Enum-Wert übergeben.



  • Vielen Dank für eure Antworten. Ich bin jetzt dank eurer Hilfe auf folgende Lösung gekommen (etwas gekürzt):

    /// \brief Enumerates all possible filter types.
      enum t_filter_id
      {
        FILTER_ID_DAUBECHIES7,  ///< ID for Daubechies 7-tap wavelet filter.
        FILTER_ID_DAUBECHIES9,  ///< ID for Daubechies 9-tap wavelet filter.
        /* ... */
      };
    
      /// \brief Defines a filter type.
      struct t_filter
      {
        const t_filter_id   id;   ///< ID of filter.
        const double*       data; ///< Store data here.
        const unsigned int  size; ///< Length of data array.
      };
    
      const double   COEFF_DAUBECHIES7[7] =
      {
        -0.09127176311424948,
        -0.05754352622849957,
         0.5912717631142470,
         1.115087052456994,
         0.5912717631142470,
        -0.05754352622849957,
        -0.09127176311424948
      };
    
      const double   COEFF_DAUBECHIES9[9] =
      {
         0.02674875741080976,
        -0.01686411844287495,
        -0.07822326652898785,
         0.2668641184428723,
         0.6029490182363579,
         0.2668641184428723,
        -0.07822326652898785,
        -0.01686411844287495,
         0.02674875741080976
      };
    
      /* ... */
    
      const t_filter FILTER_DAUBECHIES7   = { FILTER_ID_DAUBECHIES7, COEFF_DAUBECHIES7, 7 }; ///< Daubechies 7-tap wavelet filter.
      const t_filter FILTER_DAUBECHIES9   = { FILTER_ID_DAUBECHIES9, COEFF_DAUBECHIES9, 9 }; ///< Daubechies 9-tap wavelet filter.
    

    Die Arraydefinition selbst ist ja tatsächlich ein double-Pointer und passt damit super rein in das Struct. 👍


Anmelden zum Antworten