<?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[Wrapper-Klassen]]></title><description><![CDATA[<p><strong>Hallo!</strong></p>
<p>Habe das Thema unter folgendem Link schonmal angeschnitten und interessante Lösungsansätze bekommen.</p>
<p><a href="http://www.c-plusplus.net/forum/viewtopic.php?p=1806722#1806722" rel="nofollow">http://www.c-plusplus.net/forum/viewtopic.php?p=1806722#1806722</a></p>
<p><strong>Danke.</strong></p>
<p>Jetzt bin ich soweit voran gekommen, dass sich das Problem ganz massiv stellt. Ich besitze sehr viele Funktionen in meiner Engine und zudem sind die Parameterlisten meistens zwischen 2-4 Parametern des gleichen Typs (Integer) lang.</p>
<p><strong>Beispiel:</strong></p>
<pre><code class="language-cpp">int init_evasions(const board_c &amp; board, int piece, int color, int square);
int gen_captures(const board_c &amp; board, int color, int file);
</code></pre>
<p>Das ist relativ fehleranfällig, da die Parameterlisten ähnlich sind und mal ganz schnell beim Aufrufen einer Funktion die Parameter vertauscht werden können <strong>ohne, dass es vom Compiler festgestellt werden kann!</strong></p>
<p>Möchte ich diese zusätzliche Fehlerquelle abschalten, muss ich die verschiedenen Integers in den Parameterlisten entweder</p>
<p><strong>1.</strong> in eine Wrapper-Klasse packen oder<br />
<strong>2.</strong> eine Enumeration mit überladenen Operatoren einführen.</p>
<p>Option <strong>2.</strong> gefällt mir gar nicht, auch deshalb, weil ich die arithmetischen Operatoren nicht überladen möchte. Auch wurde mir hier im Forum gesagt, dass Enumertor-Typen <strong>nicht</strong> zum Rechnen gemacht sind?!</p>
<p>Daher bleibt nur die Wrapper-Klasse. Das habe ich erstmal rudimentär wie folgt implemetiert:</p>
<pre><code class="language-cpp">struct color_t {
  int a;
};

struct piece_t {
  int a;
};

struct square_t {
  int a;
};

struct file_t {
  int a;
};

struct rank_t {
  int a;
};

struct bitboard_t {
  uint64_t a;
};
</code></pre>
<p>Und schon sehen meine Funktionsdeklarationen von oben wie folgt aus:</p>
<pre><code class="language-cpp">int init_move(const board_c &amp; board, piece_t piece, color_t color, square_t square);
int gen_captures(const board_c &amp; board, color_t color, file_t file);
</code></pre>
<p>Der Compiler ist zufrieden und macht mich auf jeden kleine Nachlässigkeit aufmerksam. <strong>Meine Frage ist jetzt:</strong></p>
<p>Ist dieser Ansatz vernünftig oder ist das nicht state-of-the-art des Programmierens, Integers in kleine Wrapper-Klassen (Strukturen) zu verpacken und diese dann zu benutzen und damit zu rechnen?</p>
<p><strong>Danke für eure Kommentare!</strong></p>
]]></description><link>https://www.c-plusplus.net/forum/topic/254740/wrapper-klassen</link><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Jul 2026 18:47:32 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/254740.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 20 Nov 2009 13:36:58 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Wrapper-Klassen on Fri, 20 Nov 2009 13:42:21 GMT]]></title><description><![CDATA[<p><strong>Hallo!</strong></p>
<p>Habe das Thema unter folgendem Link schonmal angeschnitten und interessante Lösungsansätze bekommen.</p>
<p><a href="http://www.c-plusplus.net/forum/viewtopic.php?p=1806722#1806722" rel="nofollow">http://www.c-plusplus.net/forum/viewtopic.php?p=1806722#1806722</a></p>
<p><strong>Danke.</strong></p>
<p>Jetzt bin ich soweit voran gekommen, dass sich das Problem ganz massiv stellt. Ich besitze sehr viele Funktionen in meiner Engine und zudem sind die Parameterlisten meistens zwischen 2-4 Parametern des gleichen Typs (Integer) lang.</p>
<p><strong>Beispiel:</strong></p>
<pre><code class="language-cpp">int init_evasions(const board_c &amp; board, int piece, int color, int square);
int gen_captures(const board_c &amp; board, int color, int file);
</code></pre>
<p>Das ist relativ fehleranfällig, da die Parameterlisten ähnlich sind und mal ganz schnell beim Aufrufen einer Funktion die Parameter vertauscht werden können <strong>ohne, dass es vom Compiler festgestellt werden kann!</strong></p>
<p>Möchte ich diese zusätzliche Fehlerquelle abschalten, muss ich die verschiedenen Integers in den Parameterlisten entweder</p>
<p><strong>1.</strong> in eine Wrapper-Klasse packen oder<br />
<strong>2.</strong> eine Enumeration mit überladenen Operatoren einführen.</p>
<p>Option <strong>2.</strong> gefällt mir gar nicht, auch deshalb, weil ich die arithmetischen Operatoren nicht überladen möchte. Auch wurde mir hier im Forum gesagt, dass Enumertor-Typen <strong>nicht</strong> zum Rechnen gemacht sind?!</p>
<p>Daher bleibt nur die Wrapper-Klasse. Das habe ich erstmal rudimentär wie folgt implemetiert:</p>
<pre><code class="language-cpp">struct color_t {
  int a;
};

struct piece_t {
  int a;
};

struct square_t {
  int a;
};

struct file_t {
  int a;
};

struct rank_t {
  int a;
};

struct bitboard_t {
  uint64_t a;
};
</code></pre>
<p>Und schon sehen meine Funktionsdeklarationen von oben wie folgt aus:</p>
<pre><code class="language-cpp">int init_move(const board_c &amp; board, piece_t piece, color_t color, square_t square);
int gen_captures(const board_c &amp; board, color_t color, file_t file);
</code></pre>
<p>Der Compiler ist zufrieden und macht mich auf jeden kleine Nachlässigkeit aufmerksam. <strong>Meine Frage ist jetzt:</strong></p>
<p>Ist dieser Ansatz vernünftig oder ist das nicht state-of-the-art des Programmierens, Integers in kleine Wrapper-Klassen (Strukturen) zu verpacken und diese dann zu benutzen und damit zu rechnen?</p>
<p><strong>Danke für eure Kommentare!</strong></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1810986</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1810986</guid><dc:creator><![CDATA[Tomahawk]]></dc:creator><pubDate>Fri, 20 Nov 2009 13:42:21 GMT</pubDate></item><item><title><![CDATA[Reply to Wrapper-Klassen on Fri, 20 Nov 2009 13:51:42 GMT]]></title><description><![CDATA[<p>Tomahawk schrieb:</p>
<blockquote>
<p>Auch wurde mir hier im Forum gesagt, dass Enumertor-Typen <strong>nicht</strong> zum Rechnen gemacht sind?!</p>
</blockquote>
<p>Das war ich wohl damals. Wieso &quot;?!&quot;, kannst du das nicht nachvollziehen? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Tomahawk schrieb:</p>
<blockquote>
<p>Ist dieser Ansatz vernünftig oder ist das nicht state-of-the-art des Programmierens, Integers in kleine Wrapper-Klassen (Strukturen) zu verpacken und diese dann zu benutzen und damit zu rechnen?</p>
</blockquote>
<p>Der Ansatz kann durchaus vernünftig sein. Ich würde allerdings nicht Const-Referenzen verwenden, da die Klassen sehr klein sind. Bei <code>int</code> nimmst du ja auch Kopien als Parameter.</p>
<p>Ich würde aber gerne Genaueres über die einzelnen Typen erfahren. Wieso meinst du, für alle Operatorüberladung bereitstellen zu müssen? Inwiefern muss eine Farbe, eine Datei oder ein Stück (was immer <code>piece_t</code> bezeichnet) Operatoren unterstützen? Denke daran: Operatoren sollte man nur in Kontexten überladen, in denen sie der erwarteten Semantik entsprechen. Sonst sind Funktionen mit aussagekräftigen Bezeichnern besser geeignet.</p>
<p>Kannst du die einzelnen Typen etwas mehr erläutern (wofür sie stehen, welche Zustände sie haben können etc.)? Das muss nicht sehr ins Detail gehen, aber dann könnte man besser abschätzen, ob dein Vorgehen gerechtfertigt ist. Ich habe nämlich den Verdacht, dass <code>enum</code> in einigen Fällen sinnvoll wäre, Operatorüberladung hingegen nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1810994</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1810994</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Fri, 20 Nov 2009 13:51:42 GMT</pubDate></item><item><title><![CDATA[Reply to Wrapper-Klassen on Fri, 20 Nov 2009 14:02:22 GMT]]></title><description><![CDATA[<p>Dazu habe ich auch mal 'ne Frage (etwas OT, aber nur etwas <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> )<br />
Sind <code>opaque typedefs</code> eigentlich noch für C++0x vorgesehen? Das wäre ja quasi genau das, was hier benötigt wird.<br />
Das neuste Dokument im Netz, wo etwas darüber gesagt wird, ist von 2006. Zumindest kann ich nichts aktuelleres finden. Weiß jemand mehr?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1811002</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1811002</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Fri, 20 Nov 2009 14:02:22 GMT</pubDate></item><item><title><![CDATA[Reply to Wrapper-Klassen on Fri, 20 Nov 2009 14:07:00 GMT]]></title><description><![CDATA[<p>Wegen der <strong>Const Referenzen</strong>:</p>
<p>Der Parameter</p>
<pre><code class="language-cpp">board_c &amp; board
</code></pre>
<p>ist tatsächlich ein relativ grosses Objekt und muss bei mir immer übergeben werden, da ich mit mehreren Threads arbeite und es deshalb auch eine Instanz für jeden Thread gibt. Aber das ist hier nicht das Thema <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p><strong>Zu den Typen:</strong></p>
<p><strong>file_t</strong> ist eine Linie auf dem Schachbrett: 0 &lt;= file &lt;= 7, Additionen und Subtraktionen sind erwünscht.</p>
<p><strong>rank_t</strong> ist eine Reihe auf dem Schachbrett: wie file_t</p>
<p><strong>square_t</strong> ist ein Feld auf dem Schachbrett: 0 &lt;= square &lt;= 63, Additionen und Subtraktionen sind erwünscht. Ausserdem Shifts, OR und AND (&lt;&lt; &gt;&gt; | &amp;).</p>
<p><strong>color_t</strong> ist die Farbe der aktiven Seite (während der Suche): 0 &lt;= color &lt;= 1: Hier wird auch gerechnet, um die Farbe zu tauschen zB: color ^= 1 und so weiter...</p>
<p><strong>Fazit:</strong></p>
<p>Ausser mit <strong>piece_t</strong> (Schachfigur: Bauer bis König (0 &lt;= piece &lt;= 5)) wird mit allen Typen gerechnet und mit piece_t möchte ich mir evtl die Option offen halten auch rechnen zu können.</p>
<p><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>
]]></description><link>https://www.c-plusplus.net/forum/post/1811006</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1811006</guid><dc:creator><![CDATA[Tomahawk]]></dc:creator><pubDate>Fri, 20 Nov 2009 14:07:00 GMT</pubDate></item><item><title><![CDATA[Reply to Wrapper-Klassen on Fri, 20 Nov 2009 14:37:55 GMT]]></title><description><![CDATA[<p>Tomahawk schrieb:</p>
<blockquote>
<p><strong>file_t</strong> ist eine Linie auf dem Schachbrett: 0 &lt;= file &lt;= 7, Additionen und Subtraktionen sind erwünscht.</p>
<p><strong>rank_t</strong> ist eine Reihe auf dem Schachbrett: wie file_t</p>
</blockquote>
<p>Okay. Hier siehst du einen blanken <code>int</code> wahrscheinlich wegen der Typsicherheit als ungeeignet an (wobei diese auch irgendwo Grenzen haben muss). Wenn du das wirklich durchziehen willst, solltest du einen weiteren Typen <code>offset_t</code> oder so einrichten, der Differenzen von Linien/Reihen speichert. Denn es macht keinen Sinn, zwei Reihen zu addieren, hingegen kann Subtraktion erwünscht sein. Viele Operationen eines integralen Datentyps brauchst du auch gar nicht. Du kannst natürlich auch <code>rank_offset_t</code> und <code>file_offset_t</code> definieren. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Das gibt zwar etwas Aufwand, aber z.B. mit <em>Boost.Operators</em> ist auch die Operatorüberladung kein Problem mehr (<a href="http://magazin.c-plusplus.net/artikel/%DCberladung%20von%20Operatoren%20in%20CPlusPlus%20%28Teil%202%29%20-%20Einf%FChrung%20in%20boost%3A%3Aoperators" rel="nofollow">Artikel dazu</a>). Ach ja, und ich würde vielleicht gerade <code>unsigned</code> -Typen nehmen (evtl. auch <code>unsigned short</code> ), da werden Dinge wie <code>assert</code> für Wertprüfungen vereinfacht.</p>
<p>Tomahawk schrieb:</p>
<blockquote>
<p><strong>square_t</strong> ist ein Feld auf dem Schachbrett: 0 &lt;= square &lt;= 63, Additionen und Subtraktionen sind erwünscht. Ausserdem Shifts, OR und AND (&lt;&lt; &gt;&gt; | &amp;).</p>
</blockquote>
<p>Wieso brauchst du einen Typen fürs Feld? Durch die Reihe und Zeile ist doch dieses eindeutig bestimmt. Ich würde eher eine Struktur mit diesen beiden Eigenschaften als Feldpositions-Datentyp einrichten.</p>
<p>Ansonsten verstehe ich auch nicht, was du mit diesen Bitoperatoren genau willst. Wären entsprechende Nicht-Operator-Funktionen keine Alternative?</p>
<p>Tomahawk schrieb:</p>
<blockquote>
<p><strong>color_t</strong> ist die Farbe der aktiven Seite (während der Suche): 0 &lt;= color &lt;= 1: Hier wird auch gerechnet, um die Farbe zu tauschen zB: color ^= 1 und so weiter...</p>
</blockquote>
<p>Da nur zwei Zustände vorkommen, könnte man eigentlich <code>bool</code> nehmen. Allerdings scheint mir ein <code>enum</code> angebrachter. Statt rohen Operatoren, die in diesem Zusammenhang nicht besonders klar sind (wieso soll man eine Farbe XORen?), empfehle ich wiederum Funktionen.</p>
<pre><code class="language-cpp">enum color_t
{
    white,
    black,
};

void toggle_color(color_t&amp; color);
</code></pre>
<p>Tomahawk schrieb:</p>
<blockquote>
<p>Ausser mit <strong>piece_t</strong> (Schachfigur: Bauer bis König (0 &lt;= piece &lt;= 5)) wird mit allen Typen gerechnet und mit piece_t möchte ich mir evtl die Option offen halten auch rechnen zu können.</p>
</blockquote>
<p>Wieso solltest du hier rechnen können? Das wäre ein klassischer Fall für ein <code>enum</code> : Eine genau definierte Anzahl von Zuständen, welche aussagekräftige Namen haben und als gemeinsamen Typ angesprochen werden können.</p>
<p>Wie du siehst, halte ich es für wichtig, dass du etwas abstrahierst und von dem Low-Level-Bitschieberei wegkommst. Das heisst, richte für Operationen, die du mit einem Namen bezeichnen kannst, Funktionen ein. Es wird auch für dich leichter, wenn du eine Aktion gleich erkennst, als wenn du zuerst Bit für Bit nachvollziehen musst -- besonders, nachdem du den Code eine Zeit nicht mehr angeschaut hast. Die Low-Level-Operationen hast du nach wie vor -- nur sind sie entsprechend gekapselt und treten im Anwendungscode kaum noch auf. Das erleichtert auch allfällige Änderungen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1811029</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1811029</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Fri, 20 Nov 2009 14:37:55 GMT</pubDate></item><item><title><![CDATA[Reply to Wrapper-Klassen on Fri, 27 Nov 2009 07:59:47 GMT]]></title><description><![CDATA[<blockquote>
<p>Das gibt zwar etwas Aufwand, aber z.B. mit <em>Boost.Operators</em> ist auch die Operatorüberladung kein Problem mehr (<a href="http://magazin.c-plusplus.net/artikel/%DCberladung%20von%20Operatoren%20in%20CPlusPlus%20%28Teil%202%29%20-%20Einf%FChrung%20in%20boost%3A%3Aoperators" rel="nofollow">Artikel dazu</a>). Ach ja, und ich würde vielleicht gerade <code>unsigned</code> -Typen nehmen (evtl. auch <code>unsigned short</code> ), da werden Dinge wie <code>assert</code> für Wertprüfungen vereinfacht.</p>
</blockquote>
<p>Das mit dem Einsatz von unsigned Integers überlege ich schon länger. Da meine Werte (bis auf die Stellungsevaluation) immer positiv sind.</p>
<blockquote>
<p>Wieso brauchst du einen Typen fürs Feld? Durch die Reihe und Zeile ist doch dieses eindeutig bestimmt. Ich würde eher eine Struktur mit diesen beiden Eigenschaften als Feldpositions-Datentyp einrichten.</p>
</blockquote>
<p>Es wäre einfach zu langsam ein Feld über Linie und Reihe zu definieren. Dann würde ich ja einen 2-dim Vektor benötigen. Nach meiner Erfahrung verkompliziert das die Berechnungen. Ganz grob: 90% aller brettrelevanten Berechnungen sind feld-spezifisch. die übrigen 10% verteilen sich auf Linien und Reihen.</p>
<blockquote>
<p>Ansonsten verstehe ich auch nicht, was du mit diesen Bitoperatoren genau willst. Wären entsprechende Nicht-Operator-Funktionen keine Alternative?</p>
</blockquote>
<p>Bitoperationen benötige ich auf dem Brett eine Menge, hier ein Ausschnitt:</p>
<pre><code class="language-cpp">// header file

inline int square_to_file(const int square) {
  return square &amp; 7;
}

inline int square_to_rank(const int square) {
  return square &gt;&gt; 3;
}

inline int relative_square(const int color, const int square) {
  return square ^ (color * 56);
}

inline int flip_square(const int square) {
  return square ^ 56;
}

inline int file_and_rank_to_square(const int file, const int rank) {
  return file + (rank &lt;&lt; 3);
}

inline int relative_rank(const int color, const int rank)  {
  return rank ^ (color * 7);
}

inline int flip_rank(const int rank) {
  return rank ^ 7;
}
</code></pre>
<blockquote>
<p>Da nur zwei Zustände vorkommen, könnte man eigentlich <code>bool</code> nehmen. Allerdings scheint mir ein <code>enum</code> angebrachter. Statt rohen Operatoren, die in diesem Zusammenhang nicht besonders klar sind (wieso soll man eine Farbe XORen?), empfehle ich wiederum Funktionen.</p>
</blockquote>
<p>Wie kann ich einen Bool ganz schnell umkehren? Und ausserdem kann ich einen Bool meines Wissen nicht als Arrayindex einsetzen. COLOR_WHITE und COLOR_BLACK werden auch zur Indexierung von Tabellen verwendet:</p>
<pre><code class="language-cpp">// source file

int king_sq[COLORS];
int piece_ct[COLORS][PIECES];

// header file

const int COLOR_WHITE = 0;
const int COLOR_BLACK = 1;
const int COLOR_NONE = 2;

const int COLORS = 2;

inline int opposite_color(const int color) {
  return color ^ 1;
}
</code></pre>
<blockquote>
<p>Wieso solltest du hier rechnen können? Das wäre ein klassischer Fall für ein <code>enum</code> : Eine genau definierte Anzahl von Zuständen, welche aussagekräftige Namen haben und als gemeinsamen Typ angesprochen werden können.</p>
</blockquote>
<p>Stimmt, hier wird tatsächlich nicht gerechnet, habe ich übersehen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<blockquote>
<p>Wie du siehst, halte ich es für wichtig, dass du etwas abstrahierst und von dem Low-Level-Bitschieberei wegkommst. Das heisst, richte für Operationen, die du mit einem Namen bezeichnen kannst, Funktionen ein.</p>
</blockquote>
<p>Auf jeden Fall wird (fast) alles in kleine inlines verpackt, das Ausdenken von aussagekräftigen Namen dauert manchmal länger als mir lieb ist.</p>
<blockquote>
<p>Es wird auch für dich leichter, wenn du eine Aktion gleich erkennst, als wenn du zuerst Bit für Bit nachvollziehen musst -- besonders, nachdem du den Code eine Zeit nicht mehr angeschaut hast.</p>
</blockquote>
<p>Ja. Hier folgt ein typisches Beispiel wie ich im Augenblick verschachtele und verzweifelt versuche die Bitfummeleien etwas zu abstrahieren:</p>
<pre><code class="language-cpp">// header

inline int move_to(const int move) {
  return move &amp; 63;
}

inline int move_is_promotion(const int move) {
  return move &amp; IS_PROMOTION;
}

inline int move_is_enpassant(const int move) {
  return move &amp; IS_ENPASSANT;
}

inline int board_c::piece_on_square(const int square) const {
  return piece_on[square];
}

inline bool board_c::move_is_capture(const int move) const {
  return (piece_on_square(move_to(move)) != PIECE_NONE) || move_is_enpassant(move);
}

inline bool board_c::move_is_capture_or_promotion(const int move) const {
  return move_is_capture(move) || move_is_promotion(move);
}
</code></pre>
<p><strong>Danke!</strong></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1814095</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1814095</guid><dc:creator><![CDATA[Tomahawk]]></dc:creator><pubDate>Fri, 27 Nov 2009 07:59:47 GMT</pubDate></item><item><title><![CDATA[Reply to Wrapper-Klassen on Fri, 27 Nov 2009 08:08:56 GMT]]></title><description><![CDATA[<p>Nur nochmal als kleine Frage:</p>
<p>Öfters wurde hier im Forum kommentiert, dass der <code>const</code> -Bezeichner in meinen Parameterlisten unsinnig sei. Da ich erst seit kurzem programmiere und mir das selbst beibringe, weiss ich tatsächlich nicht, ob es schlecher Stil ist, das so zu tun?</p>
<p>Versuche eben, alle Daten, die von ihrer Bestimmung nicht veränderbar sein sollen als <code>const</code> zu verwalten. Bei der Übergabe von Objekten via Reference oder Pointer ist mir das schon klar, dort <em>muss</em> man das ja quasi machen.</p>
<p>Ist es bei Integers überflüssig und unsinnig mit const zu arbeiten?</p>
<p>(siehe Beispiel der Parameterlisten in meinem letzten Posting weiter oben...)</p>
<p><strong>Danke!</strong></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1814101</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1814101</guid><dc:creator><![CDATA[Tomahawk]]></dc:creator><pubDate>Fri, 27 Nov 2009 08:08:56 GMT</pubDate></item><item><title><![CDATA[Reply to Wrapper-Klassen on Fri, 27 Nov 2009 10:24:59 GMT]]></title><description><![CDATA[<p>Tomahawk schrieb:</p>
<blockquote>
<p>Nur nochmal als kleine Frage:</p>
<p>Öfters wurde hier im Forum kommentiert, dass der <code>const</code> -Bezeichner in meinen Parameterlisten unsinnig sei. Da ich erst seit kurzem programmiere und mir das selbst beibringe, weiss ich tatsächlich nicht, ob es schlecher Stil ist, das so zu tun?</p>
<p>Versuche eben, alle Daten, die von ihrer Bestimmung nicht veränderbar sein sollen als <code>const</code> zu verwalten. Bei der Übergabe von Objekten via Reference oder Pointer ist mir das schon klar, dort <em>muss</em> man das ja quasi machen.</p>
<p>Ist es bei Integers überflüssig und unsinnig mit const zu arbeiten?</p>
<p>(siehe Beispiel der Parameterlisten in meinem letzten Posting weiter oben...)</p>
<p><strong>Danke!</strong></p>
</blockquote>
<p>Ja, es ist überflüssig, da du by value übergibst, in der Funktion also mit einer Kopie arbeitest, die am Ende der Funktion ohnehin verworfen wird. Eine Änderung würde sich also lediglich innerhalb der Funktion auswirken.</p>
<p>Stefan.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1814162</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1814162</guid><dc:creator><![CDATA[DStefan]]></dc:creator><pubDate>Fri, 27 Nov 2009 10:24:59 GMT</pubDate></item><item><title><![CDATA[Reply to Wrapper-Klassen on Fri, 27 Nov 2009 12:03:55 GMT]]></title><description><![CDATA[<p>Tomahawk schrieb:</p>
<blockquote>
<p>Es wäre einfach zu langsam ein Feld über Linie und Reihe zu definieren. Dann würde ich ja einen 2-dim Vektor benötigen. Nach meiner Erfahrung verkompliziert das die Berechnungen. Ganz grob: 90% aller brettrelevanten Berechnungen sind feld-spezifisch. die übrigen 10% verteilen sich auf Linien und Reihen.</p>
</blockquote>
<p>Bei Annahmen über Geschwindigkeit wäre ich immer vorsichtig. Wenn du häufig Linien/Reihen und Felder ineinander umrechnen musst, kann das schliesslich auch etwas ausmachen. Du sagst ja, dass du noch nicht allzu lange programmierst, und Anfänger neigen dazu, Code wegen vermeintlicher Geschwindigkeitsgewinne umständlich zu machen (Premature Optimization). Kann aber auch gut sein, dass du Recht hast. Versuch, den Code einigermassen benutzerfreundlich und wartbar zu halten, und im Zweifelsfalle misst du eben die Zeit.</p>
<p>Tomahawk schrieb:</p>
<blockquote>
<p>Bitoperationen benötige ich auf dem Brett eine Menge, hier ein Ausschnitt:<br />
[...]<br />
Auf jeden Fall wird (fast) alles in kleine inlines verpackt, das Ausdenken von aussagekräftigen Namen dauert manchmal länger als mir lieb ist.</p>
</blockquote>
<p>Das ist sehr gut! <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /><br />
Ich dachte eben, du würdest die bitweisen Operatoren dauernd im Anwendungscode einsetzen, aber wenn du sie durch Funktionen verständlich machst, ist das kein Problem.</p>
<p>Tomahawk schrieb:</p>
<blockquote>
<p>Wie kann ich einen Bool ganz schnell umkehren?</p>
</blockquote>
<p>Gleich wie die anderen integralen Typen:</p>
<pre><code class="language-cpp">bool b = true;
b ^= true; // true statt 1 (spielt eigentlich keine Rolle)
</code></pre>
<p>Tomahawk schrieb:</p>
<blockquote>
<p>Und ausserdem kann ich einen Bool meines Wissen nicht als Arrayindex einsetzen.</p>
</blockquote>
<p>Kannst du schon, <code>bool</code> ist wie gesagt ein integraler Typ, der eben nur zwei Werte annehmen kann: <code>false</code> und <code>true</code> (bzw. in Zahlen ausgedrückt 0 und 1). Du könntest also höchstens ein Array mit zwei Elementen indizieren.</p>
<p>Tomahawk schrieb:</p>
<blockquote>
<p>COLOR_WHITE und COLOR_BLACK werden auch zur Indexierung von Tabellen verwendet:</p>
<pre><code class="language-cpp">// source file

int king_sq[COLORS];
int piece_ct[COLORS][PIECES];

// header file

const int COLOR_WHITE = 0;
const int COLOR_BLACK = 1;
const int COLOR_NONE = 2;

const int COLORS = 2;

inline int opposite_color(const int color) {
  return color ^ 1;
}
</code></pre>
</blockquote>
<p>Eben, nimm dafür <code>enum</code> . Enumerator-Konstanten können auch als integrale Zahlen interpretiert werden.</p>
<pre><code class="language-cpp">enum color_t
{
    WHITE,   // erster Enumerator entspricht implizit dem integralen Wert 0
    BLACK,   // entspricht automatisch dem Vorgänger+1, also 0+1 == 1
    NO_COLOR // entspricht automatisch 1+1 == 2
};

// Du kannst die Zahlen auch explizit angeben,
// das ist genau das gleiche [c]enum[/c]:
enum color_t
{
    WHITE = 0,
    BLACK = 1,
    NO_COLOR = 2
};

const int NUM_COLORS = 2; // NUM zum Verdeutlichen, dass es sich um eine Anzahl handelt
</code></pre>
<p>Der Vorteil besteht darin, dass du einen eigenen Typen für Farben hast und nicht mit <code>int</code> hantieren musst.</p>
<pre><code class="language-cpp">color_t a = BLACK;
color_t b = 1; // Fehler
</code></pre>
<p>Umgang mit Arrays:</p>
<pre><code class="language-cpp">int king_sq[NUM_COLORS];
king_sq[WHITE] = ...;
king_sq[BLACK] = ...;
</code></pre>
<p>Umkehrfunktion ( <code>static_cast</code> braucht hier keine Rechenzeit, sondern dient nur zur Umgehung der Typsicherheit):</p>
<pre><code class="language-cpp">inline color_t opposite_color(color_t color)
{
  return static_cast&lt;color_t&gt;(static_cast&lt;int&gt;(color) ^ 1);
}
</code></pre>
<p>Tomahawk schrieb:</p>
<blockquote>
<p>Öfters wurde hier im Forum kommentiert, dass der <code>const</code> -Bezeichner in meinen Parameterlisten unsinnig sei.</p>
</blockquote>
<p>Das ist in der Tat so, wie DStefan schon sagte. Du kopierst den Wert sowieso. Ob du nun die Kopie innerhalb der Funktion verändern darfst, geht die Schnittstelle nichts an. Es wird auch in der Funktion niemand daran gehindert, eine weitere Kopie zu erstellen, welche verändert werden kann. Kurz gesagt ist <code>const</code> bei Value-Parametern absolut sinnlos. Ausserdem tragen unnötige Schlüsselwörter dazu bei, dass relevante Dinge weniger gut erkennbar sind. Ich denke bei <code>const</code> in Parameterlisten z.B. immer an Zeiger oder Referenzen auf <code>const</code> , also dass ein Argument von der Funktion nicht direkt verändert wird. Das ist bei einer Kopie aber sowieso schon gegeben.</p>
<p>Glaube auch nicht, möglichst viel <code>const</code> führe zwangsläufig zu gutem und sicherem Code. Setze Const-Correctness ein, wo sie sinnvoll ist. <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>
]]></description><link>https://www.c-plusplus.net/forum/post/1814209</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1814209</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Fri, 27 Nov 2009 12:03:55 GMT</pubDate></item></channel></rss>