Copying design issue

Ok, so I pretty much have something like this (obviously significantly simplified):
1
2
3
4
5
6
7
8
9
10
11
class VirtualBase {
virtual void myMethod() = 0;
};

class VirtualBaseSource {
VirtualBase* base;

public:
VirtualBaseSource(VirtualBase* _base) : base(_base) {}
VirtualBase* getCopy();
};


Essentially what I really want to do is use VirtualBase as a Prototype for those familiar with design patterns. Now here's the issue: the easiest way to do this would be to use a copy constructor, however, since you can't dereference a pointer to an abstract class, I can't say something like
VirtualBase* getCopy() { return new VirtualBase(*base); }
I'm not even sure that'd work even if I just made a default behavior for myMethod, as I believe calling a superclass's copy constructor would only copy the fields of the superclass.

The hard way would appear to give VirtualBase a virtual copy() method, which EVERY single subclass would have to override like
Subclass::copy() { return new Subclass(*this); }
but that seems tedious, error-prone and generally just bad.

Is there a good way to do what I'm trying to do? It seems like there should be.
is there any problem if you inherit VirtualBase?
I'm not sure what you mean.
Do I have any trouble when I make a subclass of VirtualBase? Not at the moment, as long as my ConcreteSubclass overrides VirtualBase's null myMethod.

What I'm trying to do is use all subclasses of VirtualBase polymorphically as a VirtualBase.

Essentially what I want to be able to do is
1
2
3
4
5
6
7
8
VirtualBaseSource source1 = new ConcreteSubclassA();
VirtualBaseSource source2 = new ConcreteSubclassB();

VirtualBase* copy1 = source1.getCopy();
copy1->myMethod();

VirtualBase* copy2 = source2.getCopy();
copy2->myMethod();
Last edited on
in these kind of things when a base class is abstract and you want to use its functionality the best thing is to inherit it.

this way you have features of your specialized class and the base class. abstract classes are used for that only. otherwise whats the use, you can make object, or do nothing with it. making a concrete abstract is not good.

what you are doing is a association relation and anyhow you cant instantiate your VirtualBase.
what i mean is simple:

1
2
3
4
5
6
7
8
9
10
11
12
13
class VirtualBase {
virtual void myMethod() = 0;
};

class VirtualBaseSource : public VirtualBase
{

public:
VirtualBaseSource(VirtualBase* _base) : base(_base) {}
virtual void myMethod() {}

//VirtualBase* getCopy();
};


is this not possible or is there any flaw in this method?
if you are planning to inherit more classes then your getcopy() can help.
to know which class is returned you can dynamic_cast the return value to check which class is returned.

like this:

1
2
3
4
5
6
7
8
if(dynamic_cast<VirtualBaseSource *>(getCopy()) != NULL)
{
 cout << "Its a VirtualBaseSource class";
}
else
{
cout << "Some other class";
}
I have no idea why you're trying to do what you're trying to do, but I think you're missing all of my points entirely. I apologize if I'm mistaken.

There's absolutely no reason VirtualBaseSource (perhaps it would be better called a Factory rather than a Source) should be of type VirtualBase-- it needs absolutely none of the methods of VirtualBase, and I don't see how making VirtualBaseSource of type VirtualBase fixes any of the issues I have with copying. In fact, the one thing you left out of your example is how to copy and that's the only thing I'm looking for.

Your point seems to be that I somehow want to use the functionality of VirtualBase inside of VirtualBaseSource, which is not true. Even if it were true, I would just simply use the public interface of VirtualBase-- there's nothing protected inside of VirtualBase that would be of any interest to VirtualBaseSource.

I appreciate you trying to help and I'm sorry there seems to be a miscommunication between us, but I would recommend going back and reading what my problem is and the example I gave of the usage I would like in my second post (the third one on the page), then come back and respond if you would still like to help.

Thanks.
Last edited on
hmmm.. looks like im not able to understand your point..
let me read your points once again. :)

ok lets come to your point.

1
2
3
4
5
6
7
8
VirtualBaseSource source1 = new ConcreteSubclassA();
VirtualBaseSource source2 = new ConcreteSubclassB();

VirtualBase* copy1 = source1.getCopy();
copy1->myMethod();

VirtualBase* copy2 = source2.getCopy();
copy2->myMethod();



1. how will you give a pointer of VirtualBase as its an abstract class. You cant do it if i'm correct.
2. getting a copy each time might give a different instance of VirtualBase. If you want to copy your base calss and this is you want then will it be fine if you make your base a singleton??
the advantages will be there will be only one instance and whenever you want to use getcopy it will give the correct instance. and copy will be easy because it will not be a abstract class.

Please tell me if I'm getting your point correctly or still going in some other direction?
@rossman:
If you are not inheriting from virtual base class, then I don't really see the point of a protocol class (inless ofcourse you are deriving some other class from it). Or are you designing your class for future expansion? In which case, you will have to modify your class in future.

In this particular case, your virtual base class will act as a Protocol class, since it doesn't have any implementation details. (Oh yes, you will have to declare virtual destructor for that class also). But incase, if you plan to instantiate derived class, that inherits VirtualBase's interface, then you can initialize "VirtualBase *pVB " by creating "virtual constructor" for that class, which would inturn call real constructor of the derived class, which would return object to derived class. Something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class VirtualBase 
{
public:
  virtual void myMethod() = 0;
  static VirtualBase* makeVirtualBase(const& rhs);
};

class VirtualBaseSource : public VirtualBase
{
  char* member;
public:
  VirtualBaseSource(const& rhs):member(rhs.member){}
};

VirtualBase* VirtualBase::makeVirtualBase(const& rhs)
{
  return (new VirtualBaseSource(const& rhs));
}


Now when you want to use pointer to base class, VirtualBase;

1
2
VirtualBase* pVB = makeVirtualBase(const& rhs);
//You can now access Derived object via pointer to virtual base class 
Last edited on
n4nature:
what exactly you are trying to do with this code? In the beginning i was also misunderstood his problem.. His real problem is to copy the VirtualBase class somehow..!!!

now making an object of virtualbase and copying virtualbase are two totally different things!! correct?
VirtualBase is being used as interface class only, to pass on its functions to the Derived classes. And still be able to use polymorphism. Thats all.
rossman:

I believe you need the clone pattern which is totally valid and not bad. It basically is to write a virtual clone method in all derived classes of VirtualBase.

Topic archived. No new replies allowed.