<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: No Factories Necessary</title>
	<atom:link href="http://nerdland.net/2009/06/no-factories-necessary/feed/" rel="self" type="application/rss+xml" />
	<link>http://nerdland.net/2009/06/no-factories-necessary/</link>
	<description>Computer Science, Programming, and All Points Beyond</description>
	<lastBuildDate>Thu, 15 Jul 2010 12:47:41 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
	<item>
		<title>By: Matthias Vallentin</title>
		<link>http://nerdland.net/2009/06/no-factories-necessary/comment-page-1/#comment-106</link>
		<dc:creator>Matthias Vallentin</dc:creator>
		<pubDate>Sat, 18 Jul 2009 20:14:43 +0000</pubDate>
		<guid isPermaLink="false">http://nerdland.net/?p=271#comment-106</guid>
		<description>Thanks for the addendum, Tyler, my toy example works fine now!</description>
		<content:encoded><![CDATA[<p>Thanks for the addendum, Tyler, my toy example works fine now!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tyler McHenry</title>
		<link>http://nerdland.net/2009/06/no-factories-necessary/comment-page-1/#comment-102</link>
		<dc:creator>Tyler McHenry</dc:creator>
		<pubDate>Thu, 16 Jul 2009 14:46:12 +0000</pubDate>
		<guid isPermaLink="false">http://nerdland.net/?p=271#comment-102</guid>
		<description>No, those constructors are not technically needed. Well, they are needed, but they are created implicitly if they are omitted from the code. As a matter of style, though, I try to avoid using implicit constructors except for very simple classes.

As for the error you posted, that is a legitimate bug in my implementation. I have added an addendum to the main post which provides a fix for this. 

You will have to modify the method of passing the argument to the base class accordingly since the direct parent of &lt;code&gt;Derived_&lt;/code&gt; will now be &lt;code&gt;AbstractCloneableParent&lt;Base&gt;&lt;/code&gt; instead of &lt;code&gt;Base&lt;/code&gt; itself, but the same principle still applies.</description>
		<content:encoded><![CDATA[<p>No, those constructors are not technically needed. Well, they are needed, but they are created implicitly if they are omitted from the code. As a matter of style, though, I try to avoid using implicit constructors except for very simple classes.</p>
<p>As for the error you posted, that is a legitimate bug in my implementation. I have added an addendum to the main post which provides a fix for this. </p>
<p>You will have to modify the method of passing the argument to the base class accordingly since the direct parent of <code>Derived_</code> will now be <code>AbstractCloneableParent&lt;Base&gt;</code> instead of <code>Base</code> itself, but the same principle still applies.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matthias Vallentin</title>
		<link>http://nerdland.net/2009/06/no-factories-necessary/comment-page-1/#comment-100</link>
		<dc:creator>Matthias Vallentin</dc:creator>
		<pubDate>Wed, 15 Jul 2009 14:34:52 +0000</pubDate>
		<guid isPermaLink="false">http://nerdland.net/?p=271#comment-100</guid>
		<description>Thanks for your comment, Tyler. I know see what&#039;s going on in terms of object copying and the constructors in Cloneable and AbstractCloneable make sense to me. I believe, though, that 

AbstractCloneable(const AbstractCloneable&amp; copy) : T(copy) {}

and

Cloneable(const Cloneable&amp; copy) : AbstractCloneable(copy) {}

are not needed (at least not in my example). Is there a particular reason why you provide these copy constructors?

Also, I am having still trouble understanding why the compiler complains about pure functions in my example:


cloneable2.cc:68: error: cannot allocate an object of abstract type &#039;derived_&#039;
cloneable2.cc:41: note:   because the following virtual functions are pure within &#039;derived_&#039;:
cloneable2.cc:12: note: 	abstract_cloneable* abstract_cloneable::clone() const [with T = base_]


Do you have any ideas on that issue?</description>
		<content:encoded><![CDATA[<p>Thanks for your comment, Tyler. I know see what&#8217;s going on in terms of object copying and the constructors in Cloneable and AbstractCloneable make sense to me. I believe, though, that </p>
<p>AbstractCloneable(const AbstractCloneable&amp; copy) : T(copy) {}</p>
<p>and</p>
<p>Cloneable(const Cloneable&amp; copy) : AbstractCloneable(copy) {}</p>
<p>are not needed (at least not in my example). Is there a particular reason why you provide these copy constructors?</p>
<p>Also, I am having still trouble understanding why the compiler complains about pure functions in my example:</p>
<p>cloneable2.cc:68: error: cannot allocate an object of abstract type &#8216;derived_&#8217;<br />
cloneable2.cc:41: note:   because the following virtual functions are pure within &#8216;derived_&#8217;:<br />
cloneable2.cc:12: note: 	abstract_cloneable* abstract_cloneable::clone() const [with T = base_]</p>
<p>Do you have any ideas on that issue?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tyler McHenry</title>
		<link>http://nerdland.net/2009/06/no-factories-necessary/comment-page-1/#comment-99</link>
		<dc:creator>Tyler McHenry</dc:creator>
		<pubDate>Wed, 15 Jul 2009 09:51:50 +0000</pubDate>
		<guid isPermaLink="false">http://nerdland.net/?p=271#comment-99</guid>
		<description>As the compiler said, you&#039;re only allowed to pass arguments to the constructor of your immediate base class(es), and not other ancestor classes. One way to get the effect you&#039;re looking for is like this:

&lt;pre lang=&quot;cpp&quot;&gt;
Derived_::Derived_(int i)
  : Base(Base::construct(i))
{}
&lt;/pre&gt;

What this does is use the &lt;code&gt;Base_&lt;/code&gt; constructor (aliased by &lt;code&gt;Base::construct&lt;/code&gt;) to create a temporary &lt;code&gt;Base_&lt;/code&gt; object with the given parameter. Then, that object is passed to the copy constructor of &lt;code&gt;Base&lt;/code&gt; (aka &lt;code&gt;AbstractCloneable&lt;Base_&gt;&lt;/code&gt;) which in turn passes it on to the copy constructor of the &lt;code&gt;Base_&lt;/code&gt; class within the &lt;code&gt;Derived_&lt;/code&gt; object.

This requires creating a temporary object, so that&#039;s something to look out for if your classes allocate a lot of memory or consume other resources, or if they have unusual copy semantics, but this should work for most cases.

The only case in which this definitely will not work is if &lt;code&gt;Base_&lt;/code&gt; contains pure virtual functions and cannot be directly instantiated. If this is case, you are probably stuck with using a factory pattern. However, a situation in which &lt;code&gt;Base_&lt;/code&gt; would both accept a constructor parameter and also be an abstract class would seem uncommon. </description>
		<content:encoded><![CDATA[<p>As the compiler said, you&#8217;re only allowed to pass arguments to the constructor of your immediate base class(es), and not other ancestor classes. One way to get the effect you&#8217;re looking for is like this:</p>
<pre lang="cpp">
Derived_::Derived_(int i)
  : Base(Base::construct(i))
{}
</pre>
<p>What this does is use the <code>Base_</code> constructor (aliased by <code>Base::construct</code>) to create a temporary <code>Base_</code> object with the given parameter. Then, that object is passed to the copy constructor of <code>Base</code> (aka <code>AbstractCloneable&lt;Base_&gt;</code>) which in turn passes it on to the copy constructor of the <code>Base_</code> class within the <code>Derived_</code> object.</p>
<p>This requires creating a temporary object, so that&#8217;s something to look out for if your classes allocate a lot of memory or consume other resources, or if they have unusual copy semantics, but this should work for most cases.</p>
<p>The only case in which this definitely will not work is if <code>Base_</code> contains pure virtual functions and cannot be directly instantiated. If this is case, you are probably stuck with using a factory pattern. However, a situation in which <code>Base_</code> would both accept a constructor parameter and also be an abstract class would seem uncommon.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matthias Vallentin</title>
		<link>http://nerdland.net/2009/06/no-factories-necessary/comment-page-1/#comment-97</link>
		<dc:creator>Matthias Vallentin</dc:creator>
		<pubDate>Tue, 14 Jul 2009 19:12:22 +0000</pubDate>
		<guid isPermaLink="false">http://nerdland.net/?p=271#comment-97</guid>
		<description>How is it possible to initialize base classes that take a parameter from the derived classes? Here is an example.

&lt;pre lang=&quot;cpp&quot;&gt;
template &lt;typename T&gt;
class abstract_cloneable : public T
{
public:
    typedef T construct;

    abstract_cloneable() { }
    //abstract_cloneable(const abstract_cloneable&lt;T&gt;&amp; copy) : T(copy) { }
    abstract_cloneable(const T&amp; copy) : T(copy) {}
    virtual ~abstract_cloneable() { }

    virtual abstract_cloneable&lt;T&gt;* clone() const = 0;
};

template &lt;typename T&gt;
class cloneable : virtual public abstract_cloneable&lt;T&gt;
{
public:
    cloneable() { }
    //cloneable(const cloneable&lt;T&gt;&amp; copy) : abstract_cloneable&lt;T&gt;(copy) { };
    cloneable(const T&amp; copy) : abstract_cloneable&lt;T&gt;(copy) { };
    virtual ~cloneable() { }

    virtual cloneable&lt;T&gt;* clone() const
    { 
        return new cloneable&lt;T&gt;(static_cast&lt;const T&amp;&gt;(*this));
    }
};


class base_
{
protected:
    base_(int i) { }
    base_(const base_&amp; copy) { }
};

typedef abstract_cloneable&lt;base_&gt; base;

class derived_ : public base
{
public:
    // Does not work, T (base_) is not a direct base of derived_.
    derived_() : base::construct(0) { }
    derived_(int i) : base::construct(i) { }

protected:
    derived_(const derived_&amp; copy) : base(copy) { }
};

typedef cloneable&lt;derived_&gt; derived;

class derived2_ : public derived
{
public:
    derived2_() : derived() { }

protected:
    derived2_(const derived2_&amp; copy) : derived(copy) { }
};

typedef cloneable&lt;derived2_&gt; derived2;


int main()
{
    derived d = derived::construct();
    derived e = derived::construct(42);

    return 0;
}
&lt;/pre&gt;

This is the compiler error message (tested with g++ 4.3 and 4.5):

&lt;pre&gt;
cloneable2.cc: In constructor &#039;derived_::derived_()&#039;:
cloneable2.cc:44: error: type &#039;base_&#039; is not a direct base of &#039;derived_&#039;
cloneable2.cc: In constructor &#039;derived_::derived_(int)&#039;:
cloneable2.cc:46: error: type &#039;base_&#039; is not a direct base of &#039;derived_&#039;
cloneable2.cc: In function &#039;int main()&#039;:
cloneable2.cc:68: error: cannot allocate an object of abstract type &#039;derived_&#039;
cloneable2.cc:41: note:   because the following virtual functions are pure within &#039;derived_&#039;:
cloneable2.cc:12: note: 	abstract_cloneable* abstract_cloneable::clone() const [with T = base_]
cloneable2.cc:69: error: cannot allocate an object of abstract type &#039;derived_&#039;
cloneable2.cc:41: note:   since type &#039;derived_&#039; has pure virtual functions
cloneable2.cc:68: warning: unused variable &#039;d&#039;
cloneable2.cc:69: warning: unused variable &#039;e&#039;
cloneable2.cc: In constructor &#039;abstract_cloneable::abstract_cloneable() [with T = base_]&#039;:
cloneable2.cc:44:   instantiated from here
cloneable2.cc:7: error: no matching function for call to &#039;base_::base_()&#039;
cloneable2.cc:35: note: candidates are: base_::base_(const base_&amp;)
cloneable2.cc:34: note:                 base_::base_(int)
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>How is it possible to initialize base classes that take a parameter from the derived classes? Here is an example.</p>
<pre lang="cpp">
template &lt;typename T&gt;
class abstract_cloneable : public T
{
public:
    typedef T construct;

    abstract_cloneable() { }
    //abstract_cloneable(const abstract_cloneable&lt;T&gt;&amp; copy) : T(copy) { }
    abstract_cloneable(const T&amp; copy) : T(copy) {}
    virtual ~abstract_cloneable() { }

    virtual abstract_cloneable&lt;T&gt;* clone() const = 0;
};

template &lt;typename T&gt;
class cloneable : virtual public abstract_cloneable&lt;T&gt;
{
public:
    cloneable() { }
    //cloneable(const cloneable&lt;T&gt;&amp; copy) : abstract_cloneable&lt;T&gt;(copy) { };
    cloneable(const T&amp; copy) : abstract_cloneable&lt;T&gt;(copy) { };
    virtual ~cloneable() { }

    virtual cloneable&lt;T&gt;* clone() const
    {
        return new cloneable&lt;T&gt;(static_cast&lt;const T&amp;&gt;(*this));
    }
};

class base_
{
protected:
    base_(int i) { }
    base_(const base_&amp; copy) { }
};

typedef abstract_cloneable&lt;base_&gt; base;

class derived_ : public base
{
public:
    // Does not work, T (base_) is not a direct base of derived_.
    derived_() : base::construct(0) { }
    derived_(int i) : base::construct(i) { }

protected:
    derived_(const derived_&amp; copy) : base(copy) { }
};

typedef cloneable&lt;derived_&gt; derived;

class derived2_ : public derived
{
public:
    derived2_() : derived() { }

protected:
    derived2_(const derived2_&amp; copy) : derived(copy) { }
};

typedef cloneable&lt;derived2_&gt; derived2;

int main()
{
    derived d = derived::construct();
    derived e = derived::construct(42);

    return 0;
}
</pre>
<p>This is the compiler error message (tested with g++ 4.3 and 4.5):</p>
<pre>
cloneable2.cc: In constructor 'derived_::derived_()':
cloneable2.cc:44: error: type 'base_' is not a direct base of 'derived_'
cloneable2.cc: In constructor 'derived_::derived_(int)':
cloneable2.cc:46: error: type 'base_' is not a direct base of 'derived_'
cloneable2.cc: In function 'int main()':
cloneable2.cc:68: error: cannot allocate an object of abstract type 'derived_'
cloneable2.cc:41: note:   because the following virtual functions are pure within 'derived_':
cloneable2.cc:12: note: 	abstract_cloneable* abstract_cloneable::clone() const [with T = base_]
cloneable2.cc:69: error: cannot allocate an object of abstract type 'derived_'
cloneable2.cc:41: note:   since type 'derived_' has pure virtual functions
cloneable2.cc:68: warning: unused variable 'd'
cloneable2.cc:69: warning: unused variable 'e'
cloneable2.cc: In constructor 'abstract_cloneable::abstract_cloneable() [with T = base_]':
cloneable2.cc:44:   instantiated from here
cloneable2.cc:7: error: no matching function for call to 'base_::base_()'
cloneable2.cc:35: note: candidates are: base_::base_(const base_&amp;)
cloneable2.cc:34: note:                 base_::base_(int)
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Covariant, Templatized Virtual Copy Constructors « Nerdland</title>
		<link>http://nerdland.net/2009/06/no-factories-necessary/comment-page-1/#comment-14</link>
		<dc:creator>Covariant, Templatized Virtual Copy Constructors « Nerdland</dc:creator>
		<pubDate>Fri, 12 Jun 2009 12:17:58 +0000</pubDate>
		<guid isPermaLink="false">http://nerdland.net/?p=271#comment-14</guid>
		<description>[...] so this restriction does not entirely defeat the point of this exercise. [Ed: you may want to read the addendum to this article that I posted, which further addresses this [...]</description>
		<content:encoded><![CDATA[<p>[...] so this restriction does not entirely defeat the point of this exercise. [Ed: you may want to read the addendum to this article that I posted, which further addresses this [...]</p>
]]></content:encoded>
	</item>
</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced)
Database Caching 4/16 queries in 0.097 seconds using disk

Served from: nerdland.net @ 2010-09-09 18:54:37 -->