<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Properties Fragen]]></title><description><![CDATA[<p>Hi,</p>
<p>Ich häng fest <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":/"
      alt="😕"
    /><br />
Ich möchte meine Klassen um Properties erweitern. Einen ersten Ansatz hab ich schon gefunden, nur ist der recht unflexibel.<br />
Es werden Zeiger auf die getter und setter-Funktionen der Klasse gespeichert.<br />
Für elementare Typen schaut das ja immer so aus:</p>
<pre><code>int Klasse::value() const;
void Klasse::setValue( int val );
</code></pre>
<p>Für nicht-Elementare Sachen arbeitet man aber meistens mit const-Referenzen:</p>
<pre><code>const std::string&amp; Klasse::value() const;
void Klasse::setValue( const std::string&amp; val );
</code></pre>
<p>Mein Problem liegt in der Übergabe der Signatur an das Template:</p>
<pre><code>template&lt; typename PropUser, typename ValueType &gt;
class Property
{
public:
    Property( PropUser* user, void (PropUser::*setter)(ValueType), ValueType (PropUser::*getter)() const, const ValueType&amp; defaultVal=ValueType() )
    {
        m_user = user;
        set = setter;
        get = getter;
        setValue(defaultVal);
    }

[...]
private:
    PropUser* m_user;
    void (PropUser::*set)(ValueType);
    ValueType (PropUser::*get)() const;
</code></pre>
<p>So schaut es jetzt aus, und es geht damit ja nur mit der Variante für elementare Datentypen.</p>
<p>boost::mem_fn / boost::function sind wohl Alternativen, aber auch hier muss ich die Signatur mit übergeben.</p>
<p>Jetzt könnte ich natürlich 2 Property-Klassen implementieren, eine für die Referenz- die andere für die Elementar-Variante.<br />
Wenn das eine Möglichkeit ist, geht es mit virtuellen Funktionen bei Templates gut? Oder sollte ich templates spezialisieren? Wie könnte zweiteres mit den beiden Signatur-Varianten ausschauen?</p>
<p>Oder seht ihr eine Lösung mit Präprozessor-Direktiven? Dass ich also die Signatur einem Makro übergeb?</p>
<p>Für mich ist die vertiefte Verwendung von Templates, insbesondere mit den Funktionspointern, noch recht neu, und haltlos verrennt hat man sich schnell...<br />
Wenn mich jemand kurz in die richtige Richtung schupsen könnte, das wäre nett <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Danke schon mal!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/243718/properties-fragen</link><generator>RSS for Node</generator><lastBuildDate>Sat, 19 Sep 2026 18:30:28 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/243718.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 20 Jun 2009 11:23:36 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Properties Fragen on Sat, 20 Jun 2009 11:23:36 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>Ich häng fest <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":/"
      alt="😕"
    /><br />
Ich möchte meine Klassen um Properties erweitern. Einen ersten Ansatz hab ich schon gefunden, nur ist der recht unflexibel.<br />
Es werden Zeiger auf die getter und setter-Funktionen der Klasse gespeichert.<br />
Für elementare Typen schaut das ja immer so aus:</p>
<pre><code>int Klasse::value() const;
void Klasse::setValue( int val );
</code></pre>
<p>Für nicht-Elementare Sachen arbeitet man aber meistens mit const-Referenzen:</p>
<pre><code>const std::string&amp; Klasse::value() const;
void Klasse::setValue( const std::string&amp; val );
</code></pre>
<p>Mein Problem liegt in der Übergabe der Signatur an das Template:</p>
<pre><code>template&lt; typename PropUser, typename ValueType &gt;
class Property
{
public:
    Property( PropUser* user, void (PropUser::*setter)(ValueType), ValueType (PropUser::*getter)() const, const ValueType&amp; defaultVal=ValueType() )
    {
        m_user = user;
        set = setter;
        get = getter;
        setValue(defaultVal);
    }

[...]
private:
    PropUser* m_user;
    void (PropUser::*set)(ValueType);
    ValueType (PropUser::*get)() const;
</code></pre>
<p>So schaut es jetzt aus, und es geht damit ja nur mit der Variante für elementare Datentypen.</p>
<p>boost::mem_fn / boost::function sind wohl Alternativen, aber auch hier muss ich die Signatur mit übergeben.</p>
<p>Jetzt könnte ich natürlich 2 Property-Klassen implementieren, eine für die Referenz- die andere für die Elementar-Variante.<br />
Wenn das eine Möglichkeit ist, geht es mit virtuellen Funktionen bei Templates gut? Oder sollte ich templates spezialisieren? Wie könnte zweiteres mit den beiden Signatur-Varianten ausschauen?</p>
<p>Oder seht ihr eine Lösung mit Präprozessor-Direktiven? Dass ich also die Signatur einem Makro übergeb?</p>
<p>Für mich ist die vertiefte Verwendung von Templates, insbesondere mit den Funktionspointern, noch recht neu, und haltlos verrennt hat man sich schnell...<br />
Wenn mich jemand kurz in die richtige Richtung schupsen könnte, das wäre nett <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Danke schon mal!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1730010</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1730010</guid><dc:creator><![CDATA[Kurt_vom_Deich]]></dc:creator><pubDate>Sat, 20 Jun 2009 11:23:36 GMT</pubDate></item><item><title><![CDATA[Reply to Properties Fragen on Sun, 21 Jun 2009 08:07:48 GMT]]></title><description><![CDATA[<p>Na gut, war gar nicht so schwer. boost::function ist const, Referenz, etc &quot;wurscht&quot;, hauptsache der Typ stimmt.<br />
So konnte ich dieses Problem jetzt lösen:</p>
<pre><code class="language-cpp">template &lt; typename User, typename ValueType, typename Setter, typename Getter &gt;
class Property2
{
    User* m_user;
    Setter m_setter;
    Getter m_getter;
public:
    Property2( User* user, Setter set, Getter get )
     : m_user(user), m_setter(set), m_getter(get)
    {}
[...]
</code></pre>
<p>Verwendung dann so:</p>
<pre><code class="language-cpp">class TestProp2
{
    Property2&lt;TestProp2, int, boost::function&lt;void(TestProp2*, int)&gt;, boost::function&lt;int(TestProp2*) &gt; &gt; prop;
    int m_val;
    public:
        TestProp2()
        : prop(this, &amp;TestProp2::setVal, &amp;TestProp2::val)
        {
        }

        void setVal( int val )
        {
            m_val = val;
        }

        int val() const
        {
            return m_val;
        }

        Property2&lt;TestProp2, int, boost::function&lt;void(TestProp2*, int)&gt;, boost::function&lt;int(TestProp2*) &gt; &gt;&amp; property()
        {
            return prop;
        }
};
</code></pre>
<p>Nur hab ich jetzt ein weiteres Problem. Ich wollte Property-Objekte in eine map&lt;string, Property&gt; packen, damit man von außen die Klassen, die Properties nutzen ganz einfach steuern kann, ohne die Schnittestelle zu kennen:</p>
<pre><code class="language-cpp">Person mein_opa;
mein_opa.setProperty( &quot;Alter&quot;, 97 );
mein_opa.setProperty( &quot;Geburtstag&quot;, Date( 22, 1, 1912 ) );
</code></pre>
<p>Das ist aber nicht möglich, da ein Property&lt;Person, int, ...&gt; was anderes als ein Property&lt;Person, Date, ...&gt; ist, und das nicht zusammen in eine Liste gepackt werden kann. (Hätte mir ja eigentlich auch vorher schon klar sein können).</p>
<p>Wäre eine Option, die ganzen properties einzeln als Member zu speichern. Aber das impliziert, dass der Programmierer bei neuen Klassen auch seine setProperty() und getProperty()-Methode selber implementiert. Und da kann man auf die properties als Datenmember eigentlich auch gleich verzichten, da der die Schnittstelle seiner Klasse direkt verwenden kann.<br />
Ich wollte aber eine allgemeine Lösung. Wenn mir da noch jemand einen Tip geben kann, wäre nett <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Ansonten werde ich das mit der Property-Klasse erstmal verwerfen...</p>
<p>Grüße<br />
Kurt</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1730338</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1730338</guid><dc:creator><![CDATA[Kurt_vom_Deich]]></dc:creator><pubDate>Sun, 21 Jun 2009 08:07:48 GMT</pubDate></item><item><title><![CDATA[Reply to Properties Fragen on Sun, 21 Jun 2009 09:44:24 GMT]]></title><description><![CDATA[<p>Vielleicht hilft dir das hier:<br />
<a href="http://www.codeproject.com/KB/cpp/cppproperties.aspx" rel="nofollow">http://www.codeproject.com/KB/cpp/cppproperties.aspx</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1730378</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1730378</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Sun, 21 Jun 2009 09:44:24 GMT</pubDate></item><item><title><![CDATA[Reply to Properties Fragen on Sun, 21 Jun 2009 10:11:15 GMT]]></title><description><![CDATA[<p>drakon schrieb:</p>
<blockquote>
<p>Vielleicht hilft dir das hier:<br />
<a href="http://www.codeproject.com/KB/cpp/cppproperties.aspx" rel="nofollow">http://www.codeproject.com/KB/cpp/cppproperties.aspx</a></p>
</blockquote>
<p>Danke, aber wirklich hilft mir das nicht.</p>
<pre><code class="language-cpp">property&lt;PropTest,int,READ_WRITE&gt; Count;
</code></pre>
<p>Das ist ja wieder ein Member, mit fixen template-Typen. Drum kann ich das wieder nicht in ne map mit key==std::string bringen.</p>
<p>Ich hab das jetzt erstmal über Makros gemacht. Denn im Endeffekt braucht die setProperty-Methode, um flexibel zu sein, auch wieder ein boost::any als value.</p>
<p>So schauts grad aus:</p>
<pre><code class="language-cpp">#define BEGIN_READ_PROPERTY \
public: \
boost::any property(const std::string&amp; key) \
{ \
    if( false ) {} \

#define READ_PROPERTY(Key, Reader) \
    else if( #Key == key ) { \
        return boost::any(Reader()); \
    }\

#define END_READ_PROPERTY \
    else { \
        std::cout &lt;&lt; &quot;There is no Key &gt;&gt;&quot; + key + &quot;&lt;&lt;&quot; + &quot;. property() failed&quot; &lt;&lt; std::endl; \
        return boost::any(); \
    } \
} \

#define BEGIN_WRITE_PROPERTY \
public: \
bool setProperty(const std::string&amp; key, const boost::any&amp; val) \
{ \
try { \
    if( false ) {} \

#define WRITE_PROPERTY(Key, Writer, ValueType) \
    else if( #Key == key ) { \
        Writer( boost::any_cast&lt;ValueType&gt;(val) ); \
    }\

#define END_WRITE_PROPERTY \
    else { \
        std::cout &lt;&lt; &quot;There is no Key &gt;&gt;&quot; + key + &quot;&lt;&lt;&quot; + &quot;. setProperty() failed&quot; &lt;&lt; std::endl; \
    } \
} catch( boost::bad_any_cast e ) { \
    std::cout &lt;&lt; &quot;Bad Any Cast, could not set Property &gt;&gt;&quot; + key + &quot;&lt;&lt;&quot; &lt;&lt; std::endl; \
} \
} \

////////////////////////

struct TestStruct
{
    int val;
    TestStruct(int v=0)
     : val(v)
    {}
    TestStruct( const TestStruct&amp; other )
    {
        std::cout &lt;&lt; &quot;Copy&quot; &lt;&lt; std::endl;
        this-&gt;val = other.val;
    }
    const TestStruct&amp; operator=( const TestStruct&amp; other )
    {
        std::cout &lt;&lt; &quot;op =&quot; &lt;&lt; std::endl;
        this-&gt;val = other.val;
        return *this;
    }
};

//////////////////////

class MakroTest
{
    TestStruct m_val;
public:
    void setValue( const TestStruct&amp; val ) {
        m_val = val;
    }
    const TestStruct&amp; getValue() const {
        return m_val;
    }

    BEGIN_READ_PROPERTY
    READ_PROPERTY(Test1, getValue)
    END_READ_PROPERTY

    BEGIN_WRITE_PROPERTY
    WRITE_PROPERTY(Test1, setValue, TestStruct)
    END_WRITE_PROPERTY
};
</code></pre>
<p>Sind zwar mit boost::any pro Zugriff zwei Kopierkonstruktoren im Spiel, aber das ist wohl der Preis für die Flexibilität <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Thx<br />
Kurtl</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1730392</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1730392</guid><dc:creator><![CDATA[Kurt_vom_Deich]]></dc:creator><pubDate>Sun, 21 Jun 2009 10:11:15 GMT</pubDate></item><item><title><![CDATA[Reply to Properties Fragen on Sun, 21 Jun 2009 14:07:13 GMT]]></title><description><![CDATA[<p><a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-243181.html" rel="nofollow">http://www.c-plusplus.net/forum/viewtopic-var-t-is-243181.html</a><br />
<a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-222627.html" rel="nofollow">http://www.c-plusplus.net/forum/viewtopic-var-t-is-222627.html</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1730518</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1730518</guid><dc:creator><![CDATA[audacia]]></dc:creator><pubDate>Sun, 21 Jun 2009 14:07:13 GMT</pubDate></item><item><title><![CDATA[Reply to Properties Fragen on Sun, 21 Jun 2009 14:33:56 GMT]]></title><description><![CDATA[<p>Ich weiß nicht, vllt. ist ja &quot;Property&quot; der falsche Ausdruck. Ich will nicht mit C++ die Property-Syntax von C# nachbauen. (Kenn ich eh nicht persönlich, nur aus den ganzen Google-Funden) Ich möchte eigentlich nur die Möglichkeit, setter/getter-Methoden einer Klasse über eine einheitliche Schnittstelle aufzurufen. Hier property() und setProperty(). Wobei über die Keys die entsprechende Funktion aufgerufen ist.<br />
Ich will nicht speziellen Syntactic Sugar ala &quot;opa.alter = 97;&quot;.</p>
<p>Hintergrund ist der, dass ich Plugins lade. Diese Plugins sollen gesteuert werden können. Da die ladende Instanz nicht die Schnittstelle (z.B. opa.setAlter(); ) kennt, muss man einen Umweg gehen. Mit den Plugins wird eine Plugin-Description ausgeliefert. Darin stehen z.B. Sachen wie &quot;PluginName&quot;, &quot;PluginVersion&quot; oder auch &quot;PluginDependencies&quot;, wenn das Plpugin auf andere Plugins angewiesen ist. Und ebenfalls findet man dort eine Beschreibung der möglichen Properties, ala</p>
<pre><code>&lt;property key=&quot;Alter&quot;, type=&quot;int&quot;&gt;
</code></pre>
<p>Mit der Info kann ich nun &quot;ganz einfach&quot; z.B. in ner Gui Elemente zum Steuern erstellen (für int (Alter) z.B. eine &quot;SpinBox&quot;). Wenn die SpinBox ihren Wert ändert, kann das direkt an das &quot;opa&quot;-Objekt gesandt werden:</p>
<pre><code class="language-cpp">opa.setProperty(&quot;Alter&quot;, spinBox.value());
</code></pre>
<p>Und genau das macht jetzt meine Macro-Implementierung (hab sie mittlerweile erweitert, da man ja auch Vererbungshierarchien abdecken will), und ich bin furchtbar glücklich <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /> Weil der Nutzer nur simple Macros tippen muss, und nicht selber die ganzen if/else schreiben muss.</p>
<p>Der Versuch mit einer Property-Klasse war denke ich eine Sackgasse.</p>
<p>Grüßle</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1730528</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1730528</guid><dc:creator><![CDATA[Kurt_vom_Deich]]></dc:creator><pubDate>Sun, 21 Jun 2009 14:33:56 GMT</pubDate></item></channel></rss>