Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > C++ Moderated > Re: C++ languag...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 7 of 16 Topic 9571 of 9831
Post > Topic >>

Re: C++ language: Cloneable cl*****

by =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@[EMAIL PROTECTED] May 6, 2008 at 06:43 PM

On 5 Mai, 15:10, Krzysiek Czain'ski "Czajnik" <1czaj...@[EMAIL PROTECTED]
>
wrote:
> I'm working on a Cloneable concept for C++ cl*****. Here's what I
> think it should be like, however it doesn't compile :?
>
> #include <memory>
>
> class CloneableBase
> {
> public:
>     virtual ~CloneableBase() {}
> private:
>     virtual CloneableBase* doClone() const = 0;
>
> };
>
> template < typename Derived >
> class Cloneable : public CloneableBase
> {
> public:
>     typedef std::auto_ptr<Derived> AutoPtr;
>     AutoPtr clone() const { return AutoPtr( doClone() ); }
> private:
>     virtual Derived* doClone() const = 0; // COMPILE ERROR
>
> };
>
> class A : public Cloneable<A>
> {
>     virtual A* doClone() { return new A( *this ); }

Probably you meant a const version of this:

virtual A* doClone() const { return new A( *this ); }

>
> };
>
> int main()
> {
>     {
>        A a;
>        A::AutoPtr pa = a.clone();
>     }
>
> }
>
> cloneable.cpp:17: error: invalid covariant return type for 'Derived*
> Cloneable<Derived>::doClone() const [with Derived = A]'
> gcc version 4.2.3 (Gentoo 4.2.3 p1.0)
>
> MSVC.NET 2005 gives a similar error on this..
>
> The C++ standard says (10.3.5)
> The return type of an overriding function shall be either identical to
> the return type of the
> overridden function or covariant with the cl***** of the functions.
>
> Since Derived = A, it is derived from CloneableBase, through
> Cloneable<A>, so Derived is covariant with CloneableBase.
>
> Is my understanding wrong, or is this the compilers' bug, or maybe
> it's just the way it is supposed to be, and I misunderstand the C++
> standard? I'm also looking forward to comments on design/style.

First, the compilers are all correct to reject your
code, as others have already mentioned. The reason
is that you omitted to mention this part from p. 5:

"If the return type of D::f differs from the return type of
B::f, the class type in the return type of D::f shall be
complete at the point of declaration of D::f or shall be the
class type D."

In your example, Derived is incomplete at this point and
different from Cloneable.

Your problem is an interesting one and has been
issued several times (longer than a decade) in this
an related newsgroups.

IMO the next matching solution given your ansatz
is the following one. It deviates only slightly
from your original approach in that it makes the
CloneableBase::doClone() protected instead of
private - I don't think that this causes much
harm. The class template uses a static_cast, but
this should be safe, because it still is an
abstract class (implicitly) and if the provided
template parameter does not correspond to a
derived class, it should not compile.[1]

#include <memory>

class CloneableBase
{
public:
     virtual ~CloneableBase() {}
protected:
     virtual CloneableBase* doClone() const = 0;
};

template < typename Derived>
class Cloneable : public CloneableBase
{
public:
     typedef std::auto_ptr<Derived> AutoPtr;
     AutoPtr clone() const {
       return AutoPtr( static_cast<Derived*>(this->doClone()) );
     }
};

class A : public Cloneable<A>
{
     virtual A* doClone() const { return new A( *this ); }
};

int main()
{
     {
        A a;
        A::AutoPtr pa = a.clone();
     }
}

HTH & Greetings from Bremen,

Daniel Krügler

[1] If you really want, you can outsmart the mechanism like
this, but I'm not talking about Machiavelli:

class B : public Cloneable<A> {
     virtual A* doClone() const { return new A(); }
};


-- 
      [ See http://www.gotw.ca/resources/clcm.htm
for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
 




 16 Posts in Topic:
C++ language: Cloneable classes
=?ISO-8859-2?Q?Krzysiek_C  2008-05-05 07:10:17 
Re: C++ language: Cloneable classes
Marsh Ray <marsh527@[E  2008-05-05 12:34:54 
Re: C++ language: Cloneable classes
Mathias Gaunard <loufo  2008-05-06 08:21:03 
Re: C++ language: Cloneable classes
=?ISO-8859-2?Q?Krzysiek_C  2008-05-06 08:43:26 
Re: C++ language: Cloneable classes
Krzysztof Czainski <1c  2008-05-06 12:46:54 
Re: C++ language: Cloneable classes
Mathias Gaunard <loufo  2008-05-06 18:43:26 
Re: C++ language: Cloneable classes
=?ISO-8859-1?Q?Daniel_Kr=  2008-05-06 18:43:26 
Re: C++ language: Cloneable classes
Krzysztof Czainski <1c  2008-05-07 11:08:38 
Re: C++ language: Cloneable classes
Krzysztof Czainski <1c  2008-05-07 11:43:27 
Re: C++ language: Cloneable classes
dizzy <dizzy@[EMAIL PR  2008-05-07 11:43:28 
Re: C++ language: Cloneable classes
=?ISO-8859-1?Q?Daniel_Kr=  2008-05-07 18:29:53 
Re: C++ language: Cloneable classes
Krzysztof Czainski <1c  2008-05-08 21:31:47 
Re: C++ language: Cloneable classes
=?ISO-8859-1?Q?Daniel_Kr=  2008-05-09 09:15:41 
Re: C++ language: Cloneable classes
Krzysztof Czainski <1c  2008-05-09 21:26:23 
Re: C++ language: Cloneable classes
=?ISO-8859-1?Q?Daniel_Kr=  2008-05-10 14:13:29 
Re: C++ language: Cloneable classes
Krzysztof Czainski <1c  2008-05-11 16:43:29 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Sat Jul 26 3:00:42 CDT 2008.