Archived

This topic is now archived and is closed to further replies.

dcosborn

Cloning an object in C++

Recommended Posts

I've got a FileInStream object which derives from RandomAccessInStream which, in turn, derives from InStream. Both RandomAccessInStream and InStream are pure virtual, with RandomAccessInStream adding the ability to manage the current stream position. Now, with my system, its possible to clone FileInStream objects using the copy constructor. Each copy uses the same InFile object to access the file, but maintains its own current stream position. However, I need to clone a FileInStream which is hidden behind a RandomAccessInStream pointer. I need to use a RandomAccessInStream pointer because I also want to support other forms of RandomAccessInStream(ie: MemoryInStream). So, basically, I'd like to copy construct a RandomAccessInStream, which is impossible. One way of doing this would be to use a Clone() function in the InStream class. Each non-pure-virtual derived class would implement the function. However, Clone() would need to return a new InStream instance. In my case then, I'd have to cast it to a RandomAccessInStream. Either that or I'd need to make a special cloning function for each class in the heirarchy such as RandomAccessClone() and FileClone() which returns an instance of the native type. I want to find a better way of doing this! Does anyone know of something I might have overlooked? Or maybe you could just slap me for wasting so much time on such a stupid problem. Thanks. [edited by - dcosborn on April 4, 2004 4:31:43 AM]

Share this post


Link to post
Share on other sites
C++ added covariant return types in about 1996, I believe. That is, it''s legal to do this:

class Base {
public:
virtual Base * Clone(void);
};

class Derived : public Base {
public:
virtual Derived * Clone(void);
};


Just have your RandomAccessInStream::Clone() function return a RadmonAccessInstream *. It''s legal C++.

(Unless, of course, your compiler doesn''t support it, in which case you should upgrade your compiler. )

Share this post


Link to post
Share on other sites
You've just run into the prime use of a verrry interesting feature in C++, "covariant return types".

This will work:

class Base
{
public:
virtual Base* Clone() = 0;
};

class Derived1 : public Base
{
public:
virtual Derived1* Clone() { ... }
};

class Derived2: public Base
{
public:
virtual Derived2* Clone() { ... }
};


See what's going on there? You're allowed to override a function, not only by giving it the same signature, but by giving it the same signature except returning a value that is convertible to the target value. (not too clear on what exactly the limits are; for the sake of clarity, I'd only ever use it like this.)

EDIT: KHAAAAAAAAAN!!!!


"Sneftel is correct, if rather vulgar." --Flarelocke

[edited by - sneftel on April 4, 2004 4:34:23 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Sneftel
(not too clear on what exactly the limits are; for the sake of clarity, I'd only ever use it like this.)



A derived class D, when overloading a function in a accessible base class B, with return type B * or B &, may instead return D * or D & respectively. (Well they also need to have the same cv-qualifier level. i.e. If you change the return type from const B *, it needs to be replaced by const D *.) edit: See 10.3 paragraph 5 in the standard for the exact verbage.

Oh, and I was wrong, it was accepted in 1992.

quote:

EDIT: KHAAAAAAAAAN!!!!


BWA HA HA HA!



[edited by - SiCrane on April 4, 2004 4:50:24 AM]

Share this post


Link to post
Share on other sites