<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>operator overloading question</title>
		<link>http://www.allegro.cc/forums/view/608482</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Tue, 04 Oct 2011 20:22:06 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hi,</p><p>I tried to write a keyboard-class to handle all keybaordfunctions easily with one object from this class. I&#39;m using an int-array where I&#39;m saving the state of each key. The plan was to get access to this array by overloading the operator (), so that I can handle it like this:</p><p>In Keyboard.h:
</p><div class="source-code snippet"><div class="inner"><pre>  <span class="c">//(...)</span>
  public:
    <span class="k1">int</span> <span class="k1">operator</span><span class="k2">(</span><span class="k2">)</span><span class="k2">(</span><span class="k1">int</span><span class="k2">)</span><span class="k2">;</span>
  <span class="c">//(...)</span>
</pre></div></div><p>

In Keyboard.cpp:
</p><div class="source-code snippet"><div class="inner"><pre> <span class="c">//(...)</span>
 <span class="k1">int</span> Keyboard::operator<span class="k2">(</span><span class="k2">)</span><span class="k2">(</span><span class="k1">int</span> k<span class="k2">)</span><span class="k2">{</span>
   <span class="k1">return</span> button<span class="k2">[</span>k<span class="k2">]</span><span class="k2">;</span>
 <span class="k2">}</span>
 <span class="c">//(...)</span>
</pre></div></div><p>

And finally I want to use it like this:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> main<span class="k2">(</span><span class="k1">int</span> argc, <span class="k1">const</span> <span class="k1">char</span> <span class="k3">*</span>argv<span class="k2">[</span><span class="k2">]</span><span class="k2">)</span><span class="k2">{</span>
   <span class="c">//(...)</span>
   Keyboard <a href="http://www.allegro.cc/manual/key"><span class="a">key</span></a>
   std::cout <span class="k3">&lt;</span><span class="k3">&lt;</span> <a href="http://www.allegro.cc/manual/key"><span class="a">key</span></a><span class="k2">(</span>ALLEGRO_KEY_UP<span class="k2">)</span><span class="k2">;</span>   <span class="c">//returns the value of the up-key and works</span>
   Keyboard<span class="k3">*</span> key2 <span class="k3">=</span> <span class="k1">new</span> Keyboard<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
   std::cout <span class="k3">&lt;</span><span class="k3">&lt;</span> key2<span class="k2">(</span>ALLEGRO_KEY_UP<span class="k2">)</span><span class="k2">;</span>  <span class="c">//doesn't work</span>
<span class="k2">}</span>
</pre></div></div><p>

The second way returns the error &quot;error: &#39;key&#39; cannot be used as a function.<br />Why am I not able to use the overloaded Operator with an pointer to an object?</p><p>thanks for all answers <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (knudel)</author>
		<pubDate>Fri, 30 Sep 2011 18:44:13 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Because the pointer doesn&#39;t have the operator. Only the class itself has the operator. You&#39;ll have to deference it, I suppose.<br /><span class="source-code"><span class="k2">(</span><span class="k3">*</span>key2<span class="k2">)</span><span class="k2">(</span>ALLEGRO_KEY_UP<span class="k2">)</span></span>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Karadoc ~~)</author>
		<pubDate>Fri, 30 Sep 2011 18:59:23 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>That&#39;s a horrible idea. It&#39;s immoral. Please don&#39;t go crazy overloading operators. <img src="http://www.allegro.cc/forums/smileys/sad.gif" alt=":(" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Stas B.)</author>
		<pubDate>Fri, 30 Sep 2011 22:52:38 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>key-&gt;button(ALLEGRO_KEY_UP);
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (jmasterx)</author>
		<pubDate>Sat, 01 Oct 2011 00:39:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Why not overload operator [] instead?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (kazzmir)</author>
		<pubDate>Sat, 01 Oct 2011 02:21:48 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>In all honesty, I don&#39;t think a keyboard key should also be able to translate into a game button in the first place.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (jmasterx)</author>
		<pubDate>Sat, 01 Oct 2011 02:47:55 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>thanks for all answers <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /><br />Would kazzmir&#39;s solution - using the operator [] instead of () - be ok, if I use it like:
</p><div class="source-code snippet"><div class="inner"><pre> Keyboard Key<span class="k2">;</span>
Key<span class="k2">[</span>ALLEGRO_KEY_A<span class="k2">]</span>
</pre></div></div><p>

or shall I write a getButton-function?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (knudel)</author>
		<pubDate>Sat, 01 Oct 2011 15:28:03 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>It&#39;s conceptually wrong. By overloading an operator, you make a promise that the operator will behave as it suggests. The () operator is supposed to work like a function call, which means that if your object provides it, it should be conceptually similar to a function. However, in no universe is a keyboard like a function in any way, and &#39;calling the keyboard&#39; doesn&#39;t make sense.</p><p>The index operator [], which has been mentioned as an alternative, is somewhat better, but still wrong. A keyboard is not a collection of key states, it is a device that HAS a collection of key states (or it can PROVIDE one).</p><p>A full-blown &quot;OOP-correct&quot; solution would be to have the keyboard return an object that can then be used to query individual keys - naively, this object could be a simple array or vector, but for efficiency, you&#39;d probably want a specialized class that looks up individual key states as needed (&quot;lazy evaluation&quot;). In practice, however, the best solution (in terms of KISS and other software robustness principles) is to just give the Keyboard class a <tt>getKeyState(int scancode) const</tt> method. The clarity and readability you win is well worth the bit of extra typing (more so if you use an IDE with auto-completion).</p><p>Just consider hypothetical usage of your class:
</p><div class="source-code snippet"><div class="inner"><pre><span class="c">// compare this:</span>
<span class="k1">void</span> foobar<span class="k2">(</span><span class="k1">const</span> Keyboard<span class="k3">&amp;</span> kbd<span class="k2">)</span> <span class="k2">{</span>
    <span class="k1">bool</span> a <span class="k3">=</span> kbd<span class="k2">(</span><span class="n">27</span><span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
<span class="c">// against this:</span>
<span class="k1">void</span> foobar<span class="k2">(</span><span class="k1">const</span> Keyboard<span class="k3">&amp;</span> kbd<span class="k2">)</span> <span class="k2">{</span>
    <span class="k1">bool</span> a <span class="k3">=</span> kbd.getKeyStatus<span class="k2">(</span><span class="n">27</span><span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>
The first example says &quot;call the keyboard object with the number 27, and see if the result is true&quot;, while the second one says &quot;from the keyboard object, get key status 27 and see if that is true&quot;. A reader can make wild guesses as to what &quot;calling the keyboard&quot; is supposed to mean, but &quot;getting a key status&quot; is a fairly obvious thing to do, and even though both the parameter and the return value are &#39;magic constants&#39;, an educated guess would inevitably lead to the conclusion that the argument must be a scancode and the return value probably means &#39;true&#39; for &#39;pressed&#39; and &#39;false&#39; for &#39;released&#39;. Using a symbolic constant for the scancode (e.g. <tt>SCANCODE_ESC</tt>), naming the method &#39;isKeyPressed&#39; instead of &#39;getKeyStatus&#39;, and using a descriptive name for the variable would increase readability even more:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">void</span> foobar<span class="k2">(</span><span class="k1">const</span> Keyboard<span class="k3">&amp;</span> kbd<span class="k2">)</span> <span class="k2">{</span>
    <span class="k1">bool</span> escapePressed <span class="k3">=</span> kbd.isKeyPressed<span class="k2">(</span>Keyboard::SCANCODE_ESC<span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>
With code like this, the reader doesn&#39;t have to look up anything at all, because the code documents itself.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobias Dammers)</author>
		<pubDate>Sat, 01 Oct 2011 16:18:59 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://">Tobias Dammers</a> said:</div><div class="quote"><p>A full-blown &quot;OOP-correct&quot; solution would be to have the keyboard return an object that can then be used to query individual keys - naively, this object could be a simple array or vector, but for efficiency, you&#39;d probably want a specialized class that looks up individual key states as needed (&quot;lazy evaluation&quot;).</p></div></div><p>
Err... A full-blown &quot;OOP-correct&quot; solution would not expose any implementation details. There&#39;s absolutely no need for anyone to know that you use an array-like object to store your key states. In fact, returning references to objects belonging to an instance of your class is generally a horrible idea since you virtually can&#39;t protect them from being modified in unintended ways.<br />Way to go teaching newbies &quot;OOP-correct&quot; solutions.  <img src="http://www.allegro.cc/forums/smileys/undecided.gif" alt=":-/" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Stas B.)</author>
		<pubDate>Sat, 01 Oct 2011 16:46:22 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thanks a lot <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /><br />Now overloaded operators are much more plausible to me and I&#39;ll use the good code without them <img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (knudel)</author>
		<pubDate>Sat, 01 Oct 2011 16:56:44 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/608482/932808#target">Stas B.</a> said:</div><div class="quote"><p>In fact, returning references to objects belonging to an instance of your class is generally a horrible idea since you virtually can&#39;t protect them from being modified in unintended ways.</p></div></div><p>
Then return a reference to a const?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Slartibartfast)</author>
		<pubDate>Sat, 01 Oct 2011 18:55:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>O rly?</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">class</span> B <span class="k2">{</span>
<span class="number">  2</span> public:
<span class="number">  3</span> <span class="k1">char</span><span class="k3">*</span> ptr<span class="k2">;</span>
<span class="number">  4</span><span class="k2">}</span><span class="k2">;</span>
<span class="number">  5</span>
<span class="number">  6</span><span class="k1">class</span> A <span class="k2">{</span>
<span class="number">  7</span> B b<span class="k2">;</span>
<span class="number">  8</span> public:
<span class="number">  9</span>
<span class="number"> 10</span> B <span class="k1">const</span><span class="k3">&amp;</span> getB<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span> <span class="k1">return</span> b<span class="k2">;</span> <span class="k2">}</span>
<span class="number"> 11</span><span class="k2">}</span><span class="k2">;</span>
<span class="number"> 12</span>
<span class="number"> 13</span><span class="k1">int</span> main<span class="k2">(</span><span class="k2">)</span>
<span class="number"> 14</span><span class="k2">{</span>
<span class="number"> 15</span> A a<span class="k2">;</span>
<span class="number"> 16</span> B <span class="k1">const</span><span class="k3">&amp;</span> b <span class="k3">=</span> a.getB<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 17</span> B<span class="k3">&amp;</span> c <span class="k3">=</span> <span class="k2">(</span>B<span class="k3">&amp;</span><span class="k2">)</span>b<span class="k2">;</span>
<span class="number"> 18</span> c.ptr <span class="k3">=</span> NULL<span class="k2">;</span> <span class="c">// OH NOES!!!</span>
<span class="number"> 19</span>
<span class="number"> 20</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_383.html" target="_blank">getch</a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 21</span> <span class="k1">return</span> <span class="n">0</span><span class="k2">;</span>
<span class="number"> 22</span><span class="k2">}</span>
</div></div><p>

Yes. People actually do this crap. <img src="http://www.allegro.cc/forums/smileys/undecided.gif" alt=":-/" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Stas B.)</author>
		<pubDate>Sat, 01 Oct 2011 21:00:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>To me, that example demonstrates that casts are dangerous. I don&#39;t think it demonstrates that returning a reference to something internal is bad.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Karadoc ~~)</author>
		<pubDate>Sat, 01 Oct 2011 21:17:51 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/608482/932830#target">Stas B.</a> said:</div><div class="quote"><p>Yes. People actually do this crap. <img src="http://www.allegro.cc/forums/smileys/undecided.gif" alt=":-/" /></p></div></div><p>
Sure you can cast away constness, but you can also overwrite any memory you want and do whatever, so I&#39;m not sure what your point is.</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">class</span> B <span class="k2">{</span>
<span class="number">  2</span> public:
<span class="number">  3</span> <span class="k1">char</span><span class="k3">*</span> ptr<span class="k2">;</span>
<span class="number">  4</span><span class="k2">}</span><span class="k2">;</span>
<span class="number">  5</span>
<span class="number">  6</span><span class="k1">class</span> A <span class="k2">{</span>
<span class="number">  7</span> B b<span class="k2">;</span>
<span class="number">  8</span> public:
<span class="number">  9</span>
<span class="number"> 10</span> B <span class="k1">const</span><span class="k3">&amp;</span> getB<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span> <span class="k1">return</span> b<span class="k2">;</span> <span class="k2">}</span>
<span class="number"> 11</span><span class="k2">}</span><span class="k2">;</span>
<span class="number"> 12</span>
<span class="number"> 13</span><span class="k1">int</span> main<span class="k2">(</span><span class="k2">)</span>
<span class="number"> 14</span><span class="k2">{</span>
<span class="number"> 15</span> A a<span class="k2">;</span>
<span class="number"> 16</span> <span class="k1">int</span> <span class="k3">*</span> ptr <span class="k3">=</span> <span class="k2">(</span><span class="k1">int</span> <span class="k3">*</span><span class="k2">)</span><span class="k2">(</span><span class="k3">&amp;</span>a<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 17</span> <span class="k2">(</span><span class="k3">*</span>ptr<span class="k2">)</span> <span class="k3">=</span> <span class="n">9001</span><span class="k2">;</span> <span class="c">//Oh ears!</span>
<span class="number"> 18</span> <span class="k1">return</span> <span class="n">0</span><span class="k2">;</span>
<span class="number"> 19</span><span class="k2">}</span>
</div></div><p>

Additionally, why is char *ptr public? (not that it would protect you as you could just <span class="source-code"><span class="k1">int</span> <span class="k3">*</span> c <span class="k3">=</span> <span class="k2">(</span><span class="k1">int</span> <span class="k3">*</span><span class="k2">)</span><span class="k3">&amp;</span>b<span class="k2">;</span> <span class="k2">(</span><span class="k3">*</span>c<span class="k2">)</span> <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span><span class="k3">&lt;</span>code&gt; <span class="k1">or</span> something similar.</span>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Slartibartfast)</author>
		<pubDate>Sat, 01 Oct 2011 21:27:49 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The way I look at it is that const correctness is more to prevent the programmer from making stupid mistakes by warning them that they are trying to modify something that shouldn&#39;t be modified. If the programmer then decides to do something stupid and start cast-hacking then it&#39;s just bad practice on their part, and it will probably come back to bite them eventually. At least that&#39;s how I see it; the formal definition is probably different.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (someone972)</author>
		<pubDate>Sat, 01 Oct 2011 22:33:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Data members of your class are implementation details. Returning references to them means exposing implementation details. You break encapsulation for no good reason. </p><p>Let&#39;s assume that the OP writes an Allegro game using a Keyboard class that returns a reference to a key-state vector. If for whatever reason he needs to port his game to another library that only has a function to check key states, he will be stuck with his irrelevant key-state vector. If instead he implements a &#39;getKeyState&#39; member function, he may transparently re-implement it. Having the high-level keyboard wrapper mimic Allegro-specific implementation details completely defeats the purpose of having it in the first place.</p><p>Besides, your counter-arguments that you can break just about anything with explicit casting are straw-men... Normal people don&#39;t usually get tempted to break things just because they can, but they do get tempted to use nasty hacks when they think they can get away with it.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Stas B.)</author>
		<pubDate>Sun, 02 Oct 2011 03:04:32 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/608482/932870#target">Stas B.</a> said:</div><div class="quote"><p>Let&#39;s assume that the OP writes an Allegro game using a Keyboard class that returns a reference to a key-state vector. If for whatever reason he needs to port his game to another library that only has a function to check key states, he will be stuck with his irrelevant key-state vector. If instead he implements a &#39;getKeyState&#39; member function, he may transparently re-implement it. Having the high-level keyboard wrapper mimic Allegro-specific implementation details completely defeats the purpose of having it in the first place.</p></div></div><p>This is a good argument.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>Besides, your counter-arguments that you can break just about anything with explicit casting are straw-men... Normal people don&#39;t usually get tempted to break things just because they can, but they do get tempted to use nasty hacks when they think they can get away with it.</p></div></div><p>I don&#39;t think the counter-arguments were straw-men arguments. A straw-man argument when one argues against a similar but weaker position under the pretence that they are actually arguing against the original position. I don&#39;t see any straw-men here. We* are just saying that its actually <u>normal</u> for stuff to be breakable using casts and other similar hacks, and so it can&#39;t really be blamed on the reference. I think you made a good argument for why the keyboard thing shouldn&#39;t be returned as a reference to a vector, but I don&#39;t think the same can be said for all would-be-reference-returning functions.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Karadoc ~~)</author>
		<pubDate>Sun, 02 Oct 2011 04:24:25 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Karadoc said:</div><div class="quote"><p>I think you made a good argument for why the keyboard thing shouldn&#39;t be returned as a reference to a vector...</p></div></div><p>

And I thought I made a good argument for why you shouldn&#39;t expose internally-used objects that may cease existing for unforeseen reasons in the future. <img src="http://www.allegro.cc/forums/smileys/undecided.gif" alt=":-/" /><br />You just shouldn&#39;t break encapsulation without a compelling reason, even if you believe at the moment that the chances of it ever biting you are nil. I&#39;m not saying you should never do it. I&#39;m just saying you shouldn&#39;t do it by default when you have better choices.</p><p>And your arguments are straw-men because you pretend that my position is that code should be 100% fool-proof and protect masochists from themselves. In reality, all I&#39;m saying is that you shouldn&#39;t write code that&#39;s easily breakable by doing something that may superficially make sense. Especially when it costs you next to nothing to make the world a saner place.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Stas B.)</author>
		<pubDate>Sun, 02 Oct 2011 12:32:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I just opened some code that I&#39;ve written to see if I ever return a reference to internally-used objects. Here&#39;s an example of what I found.
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">const</span> std::string<span class="k3">&amp;</span> GetName<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span> <span class="k1">const</span><span class="k2">;</span>
<span class="k1">const</span> Attack<span class="k3">&amp;</span> GetAttack<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span> <span class="k1">const</span><span class="k2">;</span>
</pre></div></div><p>
To me, those functions seem fine. Both of them basically just return a reference to an internal variable. (Sometimes they return a reference to something else, for example the &quot;attack&quot; of the weapon the character is holding, or whatever.) To me it just seems completely natural and sensible to &#39;expose the internals&#39; in this case - but still, some bad stuff could happen if someone decided that the const wasn&#39;t important...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Karadoc ~~)</author>
		<pubDate>Sun, 02 Oct 2011 15:38:04 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The first function is perfectly valid.<br />Can&#39;t say much about the second one, but it looks a bit fishy. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /><br />In any case, I&#39;m not trying to profess any &quot;never do&quot; or &quot;always do&quot; rules. Such rules don&#39;t exist. I&#39;m just saying you should think before you do it. Sometimes it&#39;s just plain bad. Sometimes it&#39;s the most sensible thing to do. Most of the time, it&#39;s just not optimal.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Stas B.)</author>
		<pubDate>Sun, 02 Oct 2011 15:57:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/608482/932870#target">Stas B.</a> said:</div><div class="quote"><p>Let&#39;s assume that the OP writes an Allegro game using a Keyboard class that returns a reference to a key-state vector. If for whatever reason he needs to port his game to another library that only has a function to check key states, he will be stuck with his irrelevant key-state vector. If instead he implements a &#39;getKeyState&#39; member function, he may transparently re-implement it. Having the high-level keyboard wrapper mimic Allegro-specific implementation details completely defeats the purpose of having it in the first place.</p></div></div><p>
Okay, <b>now</b> I understand what you were getting at. In which case I guess it all depends on what exactly you mean with &quot;internally used objects&quot;. <br />Would it make sense to return a reference to one member in the key vector? That is still an internally used object.<br />Would it make sense to return iterators over the vector? It might, and would still be a reference to internally used objects.<br />I guess the real &quot;truth&quot; of the matter is that you don&#39;t want to reference implementation details, only the details given in the agreed upon interface; And if that interface specifies a vector to an array of keys (for whatever reason) then I see nothing wrong with returning a reference to the internal vector.</p><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/608482/932892#target">Stas B.</a> said:</div><div class="quote"><p>And your arguments are straw-men because you pretend that my position is that code should be 100% fool-proof and protect masochists from themselves. In reality, all I&#39;m saying is that you shouldn&#39;t write code that&#39;s easily breakable by doing something that may superficially make sense. Especially when it costs you next to nothing to make the world a saner place.
</p></div></div><p>
In reality if you cast away constness (except for extreme cases and with my consultation) you should be fired in much the same way you would be fired for directly referring to the structure of something in memory (which is also excusable and even useful in some cases).<br />IMO these two &quot;illegal&quot; actions are both similarly illegal, and if you allow the first then you should allow the second.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Slartibartfast)</author>
		<pubDate>Sun, 02 Oct 2011 16:44:42 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/608482/932910#target">Slartibartfast</a> said:</div><div class="quote"><p>Would it make sense to return a reference to one member in the key vector? That is still an internally used object.</p></div></div><p>
No. It wouldn&#39;t make sense because said vector may cease to exist in future implementations.</p><div class="quote_container"><div class="title">Slartibartfast said:</div><div class="quote"><p>Would it make sense to return iterators over the vector? It might, and would still be a reference to internally used objects.</p></div></div><p>
No. It wouldn&#39;t make sense because said vector may cease to exist in future implementations.</p><div class="quote_container"><div class="title">Slartibartfast said:</div><div class="quote"><p>I guess the real &quot;truth&quot; of the matter is that you don&#39;t want to reference implementation details, only the details given in the agreed upon interface; And if that interface specifies a vector to an array of keys (for whatever reason) then I see nothing wrong with returning a reference to the internal vector.</p></div></div><p> By your logic, you can solve the problem posed by my example by exclaiming loudly &quot;No! The vector is not irrelevant! It&#39;s the agreed upon interface! Deal with it!&quot;<br />The entire point of an interface is being abstract. If your interface mandates the use of a vector to an array of keys, then you&#39;ve got a <span class="cuss"><span><span class="cuss"><span><span class="cuss"><span>shit</span></span></span></span>ty</span></span> interface. <img src="http://www.allegro.cc/forums/smileys/rolleyes.gif" alt="::)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Stas B.)</author>
		<pubDate>Sun, 02 Oct 2011 17:04:44 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/608482/932911#target">Stas B.</a> said:</div><div class="quote"><p>No. It wouldn&#39;t make sense because said vector may cease to exist in future implementations.</p></div></div><p>
So then what do I return in GetKeyState()?</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>No. It wouldn&#39;t make sense because said vector may cease to exist in future implementations.</p></div></div><p>
It wouldn&#39;t cease to exist in future implementations because the interface specifies we return a vector. Getting rid of the vector would break the interface.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>By your logic, you can solve the problem posed by my example by exclaiming loudly &quot;No! The vector is not irrelevant! It&#39;s the agreed upon interface! Deal with it!&quot;</p></div></div><p>
Sure I can, if by definition all implementations of the interface have to return an array of keys, then that is something I can rely on to stay constant in all implementations, whether they use Allegro or SDL.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>The entire point of an interface is being abstract. If your interface mandates the use of a vector to an array of keys, then you&#39;ve got a <span class="cuss"><span><span class="cuss"><span><span class="cuss"><span>shit</span></span></span></span>ty</span></span> interface.</p></div></div><p>
How is returning an array of keys not abstract? How is it <span class="cuss"><span><span class="cuss"><span><span class="cuss"><span>shit</span></span></span></span>ty</span></span>?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Slartibartfast)</author>
		<pubDate>Sun, 02 Oct 2011 17:21:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>What do you return in GetKeyState? The state of the key. Not a reference to a member of a vector. I guess we&#39;re just arguing about semantics at this point. You can call your key-state array anything you like. The bottom line is that you&#39;ll be stuck with it, so you better think 10 times before you declare it to be a part of your interface. I&#39;ve already demonstrated why it&#39;s bad in practice. While a key vector may become a part of your interface because you defined it so, a GetKeyState member function should be a part of your interface because that&#39;s what a request to check the state of a key boils down to. I don&#39;t care about your key vector. I care about the state of the key. That&#39;s what abstraction is about.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Stas B.)</author>
		<pubDate>Sun, 02 Oct 2011 17:42:46 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/608482/932808#target">Stas B.</a> said:</div><div class="quote"><p>
In fact, returning references to objects belonging to an instance of your class is generally a horrible idea since you virtually can&#39;t protect them from being modified in unintended ways.
</p></div></div><p>
Please re-read my post. I never implied you should be returning a reference to a class internal. In fact, what I recommend is the pragmatic approach where class Keyboard simply has a getter for one key state. But even with the more elaborate solution, I did not imply any specific technical implementation of the pattern - all I said was that you could return an object that is responsible for getting keyboard states.</p><p>Obviously, if you&#39;re using C++, returning a non-const reference to a class&#39;s internals is usually a bad idea, if only because it is one of the rare situations where you can accidentally produce invalid references:
</p><div class="source-code snippet"><div class="inner"><pre>Foobar<span class="k3">*</span> foo <span class="k3">=</span> <span class="k1">new</span> Foobar<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
Baz<span class="k3">&amp;</span> baz<span class="k2">(</span>foo.getBaz<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="k1">delete</span> foo<span class="k2">;</span>
baz.quux<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> <span class="c">// boom!</span>
</pre></div></div><p>
However, there are other possible implementations:
</p><ul><li><p>class KeyStates queries the underlying keyboard API directly
</p></li><li><p>class KeyStates contains an immutable collection of key states
</p></li><li><p>class Keyboard is managed through some kind of GC system (ref counting, or whatever is feasible), and will only get deleted once all associates KeyStates objects go out of scope; this way, it is perfectly safe for class KeyStates to call back into its parent Keyboard instance
</p></li><li><p>class Keyboard is a singleton or monostate, and class KeyStates uses appropriate mechanisms to call back into it
</p></li><li><p>etc. etc. etc.
</p></li></ul><p>In fact, the reference problem is only a real problem if you&#39;re naively using a language without built-in GC; C#, Java, D, Python, and a bunch more, will allow for these things without any hassle whatsoever.</p><p>Also note that this solution does not violate encapsulation at all - the KeyStates class adheres to the &quot;do one thing&quot; philosophy, and allows for a very narrow interface, providing nothing but read-only access to a snapshot of key states. By contrast, if you pass an instance class Keyboard into a function, that function can do EVERYTHING the Keyboard class exposes - read key states, change modifier states, set LED status, change keyboard layout, etc.; OTOH, if you only pass an immutable KeyStates object, the function can do nothing but read key states.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobias Dammers)</author>
		<pubDate>Sun, 02 Oct 2011 18:13:19 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Returning a reference to a <span class="source-code"><span class="k1">const</span></span> should be a contract between the caller and object that the referenced object will persist for at least as long as the returning object itself and that the caller is not to modify it. So long as this contract is upheld then there&#39;s no harm. Even better if the returned object is immutable.</p><p>I would agree that an object that exposes a keyboard state should support an interface to check the state of a key rather than returning the internal state. You might offer a way to query multiple keys at a time, but I would prefer that interface to return a copy of internal state.</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">void</span> Keyboard::getKeyStates<span class="k2">(</span>std::map<span class="k3">&lt;</span><span class="k1">int</span>,bool&gt; <span class="k3">&amp;</span> in_out<span class="k2">)</span> <span class="k1">const</span>
<span class="k2">{</span>
    <span class="k1">for</span><span class="k2">(</span>std::map<span class="k3">&lt;</span><span class="k1">int</span>,bool&gt;::iterator it <span class="k3">=</span> in_out.begin<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
            it <span class="k3">!</span><span class="k3">=</span> in_out.end<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
            it<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span>
    <span class="k2">{</span>
        <span class="k1">int</span> <a href="http://www.allegro.cc/manual/key"><span class="a">key</span></a> <span class="k3">=</span> it-&gt;first<span class="k2">;</span>

        results<span class="k2">[</span><a href="http://www.allegro.cc/manual/key"><span class="a">key</span></a><span class="k2">]</span> <span class="k3">=</span> this-&gt;getKeyState<span class="k2">(</span><a href="http://www.allegro.cc/manual/key"><span class="a">key</span></a><span class="k2">)</span><span class="k2">;</span>
    <span class="k2">}</span>
<span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (bamccaig)</author>
		<pubDate>Sun, 02 Oct 2011 18:40:39 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/608482/932916#target">Tobias Dammers</a> said:</div><div class="quote"><p>Also note that this solution does not violate encapsulation at all - the KeyStates class adheres to the &quot;do one thing&quot; philosophy, and allows for a very narrow interface, providing nothing but read-only access to a snapshot of key states. By contrast, if you pass an instance class Keyboard into a function, that function can do EVERYTHING the Keyboard class exposes - read key states, change modifier states, set LED status, change keyboard layout, etc.; OTOH, if you only pass an immutable KeyStates object, the function can do nothing but read key states.
</p></div></div><p>
That&#39;s actually a pretty sound solution. I guess I misunderstood your post.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Stas B.)</author>
		<pubDate>Sun, 02 Oct 2011 19:02:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/608482/932920#target">Stas B.</a> said:</div><div class="quote"><p>
That&#39;s actually a pretty sound solution. I guess I misunderstood your post.
</p></div></div><p>
No harm done <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobias Dammers)</author>
		<pubDate>Tue, 04 Oct 2011 20:22:06 +0000</pubDate>
	</item>
</rss>
