<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>C++ derived classes, grandchildren&lt;--&gt;grandparents</title>
		<link>http://www.allegro.cc/forums/view/599083</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Tue, 03 Feb 2009 02:25:37 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Our class is creating shapes in OpenGL.  We are given the drawing routines, while we need to calculate the position of each of the polygons&#39; points ourselves.</p><p>Since there are multiple shapes, I define a base class, Shape.</p><p>One shape is a Cube, with a 1:1:1 ratio of all its sides.  I&#39;m given the cube&#39;s diameter in a text file, and set its height, width, and depth to the same value (diameter / 2) and center it around a point.</p><p>Another shape is a Box, where height, width, and depth are defined differently.</p><p>Is a Box derived from Cube, or Cube from Box?</p><p>I would think &quot;Cube is a Box with 1&#39;s as its height/width/depth&quot;.  It&#39;s most logical to me.</p><p>But if I&#39;m overriding the &quot;read the dimensions in from a stream&quot;, I have a problem:</p><ol><li><p> Shape will read in the shape&#39;s color (for all polygons) and the coordinates where its center will be located (x, y, and z axis).</p></li><li><p> Box will let Shape read in the above, and then it will read in the height, width, and depth it needs.</p></li></ol><p>
At this point, all is fine.  But when I want to create Cube, I can&#39;t read in 3 points for its dimensions: I can only read in 1 (the file won&#39;t specify H,W, and D... just one of them).</p><p>If Cube is derived from Shape, I don&#39;t have problems, though I have a lot of duplicated code, which is what I want to avoid.</p><p>But if Cube is derived from Box (which is derived from Shape), both Shape and Box try to read in their streams before Cube &quot;gets control&quot; of the stream.</p><p>If Cube is declared like this:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">class</span> Cube
   <span class="k2">:</span> <span class="k1">public</span> Box
<span class="k2">{</span>
   <span class="c">// ...</span>
<span class="k2">}</span>
</pre></div></div><p>

...and I wanted to do something like this:
</p><div class="source-code snippet"><div class="inner"><pre>Cube::Cube<span class="k2">(</span>std::istream<span class="k3">&amp;</span> is<span class="k2">)</span>
   <span class="k2">:</span> Shape<span class="k2">(</span>is<span class="k2">)</span>
<span class="k2">{</span>
   <span class="k1">float</span> diameter<span class="k2">;</span>
   is <span class="k3">&gt;</span><span class="k3">&gt;</span> diameter<span class="k2">;</span>
   dimensions <span class="k3">=</span> Point<span class="k2">(</span>diameter, diameter, diameter<span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>

...then I get a compile error:
</p><div class="source-code snippet"><div class="inner"><pre>Cube.cpp: In constructor <span class="s">'Cube::Cube()'</span><span class="k2">:</span>
Cube.cpp:10: error: type <span class="s">'Shape'</span> is <span class="k1">not</span> a direct base of <span class="s">'Cube'</span>
</pre></div></div><p>

But again, if I change the constructor to:
</p><div class="source-code snippet"><div class="inner"><pre>Cube::Cube<span class="k2">(</span>std::istream<span class="k3">&amp;</span> is<span class="k2">)</span>
   <span class="k2">:</span> Box<span class="k2">(</span>is<span class="k2">)</span>
<span class="k2">{</span>
   <span class="c">// ...</span>
<span class="k2">}</span>
</pre></div></div><p>
...then it tries to read in H, W, and D which is not what I want.</p><p>Any suggestions on how I can call the super class of the current object&#39;s super class?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (OnlineCop)</author>
		<pubDate>Sun, 01 Feb 2009 08:32:32 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;m afraid you have to call a constructor on the immediate base class. Otherwise, a calls could not be sure that its constructor had actually been called which could cause somethings to break.</p><p>What you could do:</p><p>1. Have Box provide a default constructor which Cube calls.</p><p>2. Don&#39;t use the constructor for input purposes, instead, have other functions which extract the input and then invoke the classes constructor. Perhaps you don&#39;t need a cube class at all; instead, just construct a Box with all dimensions the same.</p><p>3. Have Box and Cube inherit from a class BoxBase which has has all the box methods but doesn&#39;t try to read in the input. The Box and Cube classes just change how they handle input.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Wetimer)</author>
		<pubDate>Sun, 01 Feb 2009 09:05:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I have #1, so Shape can be called with 0 arguments, or with a stream (and therefore, its derived class Box has the same).</p><p>For #2, Shape&#39;s constructor itself doesn&#39;t read in the data from the file; it calls a readData() function which does it.  Maybe I should have Cube call Shape&#39;s readData() function?</p><p>#3 actually sounds pretty good.  I&#39;ll try this approach first, then work my way back.  Thanks for suggesting it.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (OnlineCop)</author>
		<pubDate>Sun, 01 Feb 2009 09:16:25 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;m thinking <tt>Cube</tt> should derive from <tt>Box</tt>, but the necessary loading operation for <tt>Box</tt> should be overridden in <tt>Cube</tt>... <img src="http://www.allegro.cc/forums/smileys/undecided.gif" alt=":-/" /> So the loading should be broken off into a virtual method that can be overridden in derived classes.</p><p><sub>Disclaimer: I&#39;m drunk... I apologize if that was already said...</sub>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (bamccaig)</author>
		<pubDate>Sun, 01 Feb 2009 10:39:04 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Does anyone else see &quot;//--&gt;&quot; above the allegro.cc logo on this page only?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Schyfis)</author>
		<pubDate>Sun, 01 Feb 2009 10:51:07 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I see it.  Probably has to do with me having &quot;&lt;--&gt;&quot; in the title of the thread.  It must have thought MY &quot;--&gt;&quot; was its own &quot;--&gt;&quot;.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (OnlineCop)</author>
		<pubDate>Sun, 01 Feb 2009 11:05:21 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hmm... I don&#39;t like having the constructor do anything other than initializing variables with default values, since the only way to handle errors there is with an exception.</p><p>I would create a virtual load method in Shape, then let the shapes handle it correctly. Maybe even making the class abstract to prevent anyone from instantiating it:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">class</span> Shape <span class="k2">{</span>
    public:
        <span class="k1">virtual</span> <span class="k1">bool</span> Load<span class="k2">(</span>std::istream<span class="k3">&amp;</span> is<span class="k2">)</span> <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>
<span class="k2">}</span><span class="k2">;</span>

<span class="k1">class</span> Box <span class="k2">{</span>
    public:
        <span class="k1">virtual</span> <span class="k1">bool</span> Load<span class="k2">(</span>std::istream <span class="k3">&amp;</span>is<span class="k2">)</span> <span class="k2">{</span>
            <span class="c">// TODO: magic</span>
        <span class="k2">}</span>
<span class="k2">}</span><span class="k2">;</span>
</pre></div></div><p>

Since all shapes appear to load data from files, it would be useful to have the function there (unless the shapes are DTOs and you don&#39;t want methods other than the constructor in them).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ReyBrujo)</author>
		<pubDate>Sun, 01 Feb 2009 11:34:34 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I have #1, so Shape can be called with 0 arguments, or with a stream (and therefore, its derived class Box has the same).
</p></div></div><p>

This doesn&#39;t follow. Constructors are not inherited: all derived classes might have completely different signatures and have no use for some or all of the base class constructor signatures. (You might provide a protected default constructor of Cube, to be only used by the derived classes.)</p><p>The problem itself is well-known (<a href="http://en.wikipedia.org/wiki/Circle-ellipse_problem">Modelling Circle-Ellipse</a>), although as I understand it won&#39;t be that bad if the instances are immutable. (This has not so much to do with constructors, but what you might run into modeling things like geometrical shapes as an inheritance hierarchy.)</p><p>However, if Box derives from Cube and adds 2 more lengths to it, I don&#39;t see why the current approach should be causing problems.</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="p">#include &lt;iostream&gt;</span></td></tr><tr><td class="number">2</td><td><span class="p">#include &lt;sstream&gt;</span></td></tr><tr><td class="number">3</td><td><span class="p">#include &lt;stdexcept&gt;</span></td></tr><tr><td class="number">4</td><td>&#160;</td></tr><tr><td class="number">5</td><td><span class="k1">struct</span> shape_construction_error: <span class="k1">public</span> std::runtime_error</td></tr><tr><td class="number">6</td><td><span class="k2">{</span></td></tr><tr><td class="number">7</td><td>    shape_construction_error<span class="k2">(</span><span class="k1">const</span> std::string<span class="k3">&amp;</span> msg<span class="k2">)</span><span class="k2">:</span> std::runtime_error<span class="k2">(</span>msg<span class="k2">)</span> <span class="k2">{</span><span class="k2">}</span></td></tr><tr><td class="number">8</td><td><span class="k2">}</span><span class="k2">;</span></td></tr><tr><td class="number">9</td><td>&#160;</td></tr><tr><td class="number">10</td><td>&#160;</td></tr><tr><td class="number">11</td><td><span class="k1">class</span> Shape</td></tr><tr><td class="number">12</td><td><span class="k2">{</span></td></tr><tr><td class="number">13</td><td><span class="k2">}</span><span class="k2">;</span></td></tr><tr><td class="number">14</td><td>&#160;</td></tr><tr><td class="number">15</td><td><span class="k1">class</span> Cube: <span class="k1">public</span> Shape</td></tr><tr><td class="number">16</td><td><span class="k2">{</span></td></tr><tr><td class="number">17</td><td>protected:</td></tr><tr><td class="number">18</td><td>    <span class="k1">int</span> a<span class="k2">;</span></td></tr><tr><td class="number">19</td><td>public:</td></tr><tr><td class="number">20</td><td>    Cube<span class="k2">(</span>std::istream<span class="k3">&amp;</span> is<span class="k2">)</span></td></tr><tr><td class="number">21</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">22</td><td>        <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span><span class="k2">(</span>is <span class="k3">&gt;</span><span class="k3">&gt;</span> a<span class="k2">)</span><span class="k2">)</span></td></tr><tr><td class="number">23</td><td>           <span class="k1">throw</span> shape_construction_error<span class="k2">(</span><span class="s">"failed cube"</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">24</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">25</td><td>    std::ostream<span class="k3">&amp;</span> print<span class="k2">(</span>std::ostream<span class="k3">&amp;</span> os<span class="k2">)</span> <span class="k1">const</span></td></tr><tr><td class="number">26</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">27</td><td>        <span class="k1">return</span> os <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">'['</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> a <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">", "</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> a <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">", "</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> a <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"]\n"</span><span class="k2">;</span></td></tr><tr><td class="number">28</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">29</td><td><span class="k2">}</span><span class="k2">;</span></td></tr><tr><td class="number">30</td><td>&#160;</td></tr><tr><td class="number">31</td><td><span class="k1">class</span> Box: <span class="k1">public</span> Cube</td></tr><tr><td class="number">32</td><td><span class="k2">{</span></td></tr><tr><td class="number">33</td><td>protected:</td></tr><tr><td class="number">34</td><td>    <span class="k1">int</span> b, c<span class="k2">;</span></td></tr><tr><td class="number">35</td><td>public:</td></tr><tr><td class="number">36</td><td>    Box<span class="k2">(</span>std::istream<span class="k3">&amp;</span> is<span class="k2">)</span><span class="k2">:</span> Cube<span class="k2">(</span>is<span class="k2">)</span></td></tr><tr><td class="number">37</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">38</td><td>        <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span><span class="k2">(</span>is <span class="k3">&gt;</span><span class="k3">&gt;</span> b <span class="k3">&gt;</span><span class="k3">&gt;</span> c<span class="k2">)</span><span class="k2">)</span></td></tr><tr><td class="number">39</td><td>            <span class="k1">throw</span> shape_construction_error<span class="k2">(</span><span class="s">"failed box"</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">40</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">41</td><td>    std::ostream<span class="k3">&amp;</span> print<span class="k2">(</span>std::ostream<span class="k3">&amp;</span> os<span class="k2">)</span> <span class="k1">const</span></td></tr><tr><td class="number">42</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">43</td><td>        <span class="k1">return</span> os <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">'['</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> a <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">", "</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> b <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">", "</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> c <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"]\n"</span><span class="k2">;</span></td></tr><tr><td class="number">44</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">45</td><td><span class="k2">}</span><span class="k2">;</span></td></tr><tr><td class="number">46</td><td>&#160;</td></tr><tr><td class="number">47</td><td><span class="k1">int</span> main<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">48</td><td><span class="k2">{</span></td></tr><tr><td class="number">49</td><td>    std::stringstream a<span class="k2">(</span><span class="s">"5"</span><span class="k2">)</span>, b<span class="k2">(</span><span class="s">"10 12 14"</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">50</td><td>    Cube c1<span class="k2">(</span>a<span class="k2">)</span><span class="k2">;</span> c1.print<span class="k2">(</span>std::cout<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">51</td><td>    Box c2<span class="k2">(</span>b<span class="k2">)</span><span class="k2">;</span> c2.print<span class="k2">(</span>std::cout<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">52</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

If a cube fundamentally behaves the same as a box, except having all sides equal, you might just use the same class for it and, for example, allow creation of two types of boxes (cubes/boxes) using the <a href="http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.8">&quot;named constructor idiom&quot;</a>.</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="p">#include &lt;iostream&gt;</span></td></tr><tr><td class="number">2</td><td><span class="p">#include &lt;sstream&gt;</span></td></tr><tr><td class="number">3</td><td><span class="p">#include &lt;stdexcept&gt;</span></td></tr><tr><td class="number">4</td><td>&#160;</td></tr><tr><td class="number">5</td><td><span class="k1">struct</span> shape_construction_error: <span class="k1">public</span> std::runtime_error</td></tr><tr><td class="number">6</td><td><span class="k2">{</span></td></tr><tr><td class="number">7</td><td>    shape_construction_error<span class="k2">(</span><span class="k1">const</span> std::string<span class="k3">&amp;</span> msg<span class="k2">)</span><span class="k2">:</span> std::runtime_error<span class="k2">(</span>msg<span class="k2">)</span> <span class="k2">{</span><span class="k2">}</span></td></tr><tr><td class="number">8</td><td><span class="k2">}</span><span class="k2">;</span></td></tr><tr><td class="number">9</td><td>&#160;</td></tr><tr><td class="number">10</td><td><span class="k1">class</span> Shape</td></tr><tr><td class="number">11</td><td><span class="k2">{</span></td></tr><tr><td class="number">12</td><td><span class="k2">}</span><span class="k2">;</span></td></tr><tr><td class="number">13</td><td>&#160;</td></tr><tr><td class="number">14</td><td><span class="k1">class</span> Box: <span class="k1">public</span> Shape</td></tr><tr><td class="number">15</td><td><span class="k2">{</span></td></tr><tr><td class="number">16</td><td>protected:</td></tr><tr><td class="number">17</td><td>    <span class="k1">int</span> a, b, c<span class="k2">;</span></td></tr><tr><td class="number">18</td><td>public:</td></tr><tr><td class="number">19</td><td>    std::ostream<span class="k3">&amp;</span> print<span class="k2">(</span>std::ostream<span class="k3">&amp;</span> os<span class="k2">)</span> <span class="k1">const</span></td></tr><tr><td class="number">20</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">21</td><td>        <span class="k1">return</span> os <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">'['</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> a <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">", "</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> b <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">", "</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> c <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"]\n"</span><span class="k2">;</span></td></tr><tr><td class="number">22</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">23</td><td>&#160;</td></tr><tr><td class="number">24</td><td>    <span class="c">//construction of two types of boxes only possible through these static methods</span></td></tr><tr><td class="number">25</td><td>    <span class="k1">static</span> Box make_cube<span class="k2">(</span>std::istream<span class="k3">&amp;</span> is<span class="k2">)</span></td></tr><tr><td class="number">26</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">27</td><td>        <span class="k1">int</span> a<span class="k2">;</span></td></tr><tr><td class="number">28</td><td>        <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span><span class="k2">(</span>is <span class="k3">&gt;</span><span class="k3">&gt;</span> a<span class="k2">)</span><span class="k2">)</span></td></tr><tr><td class="number">29</td><td>            <span class="k1">throw</span> shape_construction_error<span class="k2">(</span><span class="s">"failed cube"</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">30</td><td>        <span class="k1">return</span> Box<span class="k2">(</span>a<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">31</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">32</td><td>&#160;</td></tr><tr><td class="number">33</td><td>    <span class="k1">static</span> Box make_box<span class="k2">(</span>std::istream<span class="k3">&amp;</span> is<span class="k2">)</span></td></tr><tr><td class="number">34</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">35</td><td>        <span class="k1">int</span> a, b, c<span class="k2">;</span></td></tr><tr><td class="number">36</td><td>        <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span><span class="k2">(</span>is <span class="k3">&gt;</span><span class="k3">&gt;</span> a <span class="k3">&gt;</span><span class="k3">&gt;</span> b <span class="k3">&gt;</span><span class="k3">&gt;</span> c<span class="k2">)</span><span class="k2">)</span></td></tr><tr><td class="number">37</td><td>            <span class="k1">throw</span> shape_construction_error<span class="k2">(</span><span class="s">"failed box"</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">38</td><td>        <span class="k1">return</span> Box<span class="k2">(</span>a, b, c<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">39</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">40</td><td>&#160;</td></tr><tr><td class="number">41</td><td>private:</td></tr><tr><td class="number">42</td><td>    <span class="c">//cube constructor</span></td></tr><tr><td class="number">43</td><td>    Box<span class="k2">(</span><span class="k1">int</span> a<span class="k2">)</span><span class="k2">:</span> a<span class="k2">(</span>a<span class="k2">)</span>, b<span class="k2">(</span>a<span class="k2">)</span>, c<span class="k2">(</span>a<span class="k2">)</span> <span class="k2">{</span><span class="k2">}</span></td></tr><tr><td class="number">44</td><td>    <span class="c">//box constructor</span></td></tr><tr><td class="number">45</td><td>    Box<span class="k2">(</span><span class="k1">int</span> a, <span class="k1">int</span> b, <span class="k1">int</span> c<span class="k2">)</span><span class="k2">:</span> a<span class="k2">(</span>a<span class="k2">)</span>, b<span class="k2">(</span>b<span class="k2">)</span>, c<span class="k2">(</span>c<span class="k2">)</span> <span class="k2">{</span><span class="k2">}</span></td></tr><tr><td class="number">46</td><td><span class="k2">}</span><span class="k2">;</span></td></tr><tr><td class="number">47</td><td>&#160;</td></tr><tr><td class="number">48</td><td><span class="k1">int</span> main<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">49</td><td><span class="k2">{</span></td></tr><tr><td class="number">50</td><td>    std::stringstream a<span class="k2">(</span><span class="s">"5"</span><span class="k2">)</span>, b<span class="k2">(</span><span class="s">"10 12 14"</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">51</td><td>    Box c1 <span class="k3">=</span> Box::make_cube<span class="k2">(</span>a<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">52</td><td>    c1.print<span class="k2">(</span>std::cout<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">53</td><td>    Box c2 <span class="k3">=</span> Box::make_box<span class="k2">(</span>b<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">54</td><td>    c2.print<span class="k2">(</span>std::cout<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">55</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

(Whether you put objects into the final state in the constructor and throw exceptions if you can&#39;t do so, or you just create default instances and load them later - again throwing an exception or returning success/failure, seems a bit like a matter of taste (the load+error code method requiring somewhat more discipline from the programmer).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (anonymous)</author>
		<pubDate>Sun, 01 Feb 2009 19:33:49 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p><b>anonymous</b>, I mis-worded that.  It&#39;s not that &quot;since my constructor has ___, my derived classes required me to implement the same functionality.&quot;  Instead, I was trying to say that I had implemented them all the same, just because each of my derived classes thus far have needed the same functionality.</p><p>I went with the approach of having a BasicBox object that derived from Shape, and then Cube and Box both derived from BasicBox.  That way, BasicBox didn&#39;t actually draw any information from the file, though BasicBox&#39;s parent, Shape, did.</p><p>I essentially wanted to &quot;skip a generation&quot; when I was loading data.  The Shape NEEDED to load the object&#39;s center X,Y,Z coordinates as well as the shape&#39;s color, and all Shape formats (current and planned) would start their data with the same structure.  Having BasicBox was a good trade-off, though it seems a bit clunky if I will have more related types in the future, like a Sphere and and Ovoid.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (OnlineCop)</author>
		<pubDate>Mon, 02 Feb 2009 00:49:30 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>No need for dedicated Cube and Box classes, really. Just Box, and give it two ctors: one with a single size argument, one with 3 sizes. Everything else is pretty much the same, at least the difference doesn&#39;t really justify dedicated classes.<br />If, OTOH, you are required to use dedicated classes, I&#39;d use a hierarchy something like:
</p><pre>
Shape (abstract)
 +- BoxShape (abstract, introduces getW(), getH(), getD() or whatever as abstract methods, and implements the common functionality for box and cube that doesn&#39;t work for other shapes like spheres)
      +- Cube (overloads all 3 getXXX() methods to return the same member var&#39;s value)
      +- Box (overloads getXXX() to return the individual components)
</pre><p>
The reason why I&#39;m saying this is that conceptually, you can argue two ways - either a cube is a special case of a box; if you go this route, then you can use the general-case code for both. Or a box and a cube are two different things, both inheriting from an abstract common concept; in this case, the common abstract base class BoxShape represents the underlying concept, with Box and Cube as its (otherwise independent) manifestations.</p><p>More practically, if your Box has a member var &quot;size&quot;, and you derive Cube from Box, then you can either re-use &quot;size&quot; as one of the dimensional sizes (which is not a good thing really - which of the dimensions is &quot;the&quot; size? they&#39;re all equivalent, and none is functionally the same as a cube&#39;s size; in other words, such a construct would violate the rule that the meaning of a member variable should not change from a parent class to any of its descendants), or you can decide not to use it at all and introduce three new member variables instead, ignoring the inherited &quot;size&quot; (but this is a bad thing too, because it leaves you with an unnecessary variable - this is both slightly wasteful and, much worse, potentionally misleading).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobias Dammers)</author>
		<pubDate>Tue, 03 Feb 2009 02:25:37 +0000</pubDate>
	</item>
</rss>
