-1

I have a pointer to an object of type A:

A* a;

It is set by a parameter in an initialization function, but I don't have any way of knowing whether a type derived from A is used instead, and I can't test for all possibilities (and shouldn't have to, anyway).

I need to make an exact copy of the object pointed to by a, and have the new duplicate object pointed to by a new pointer b. It must copy all of the data, rather than just the pointer itself, because I must NOT overwrite the original data when I later change *b. I could try this:

A* a = param_a;

A temp = *a;

A* b = new A();

*b = temp;

But I'm afraid that when I try to store the data from *a into temp, if it wasn't actually instantiated as an A then there won't be enough space to hold it. Then when I instantiate *b as an A, and then replace it with temp, again there wouldn't be enough space. How can I do this?

ThisIsMe
  • 1
  • 3
  • 1
    Does this answer your question? [Copying a Polymorphic object in C++](https://stackoverflow.com/questions/5148706/copying-a-polymorphic-object-in-c) – Richard Critten Oct 05 '21 at 16:32
  • I don't think that will work, because it seems to say I must either make a clone function and then override it in each derived type (but I want it to work with all derived types without making people who create them implement specific clone functions to ensure they work properly), or I can use a template. Though I could theoretically use a template, I don't think that will work either, for two reasons: – ThisIsMe Oct 05 '21 at 16:49
  • - Templates can allow any possible type, but I need to restrict it to only subtypes of A, which I don't think I can do with a template (can I?). – ThisIsMe Oct 05 '21 at 16:54
  • - I have to make a list of objects of another type (let's call it X) and each one must ultimately be able to make a list of objects of some type either A or derived from A, but they must all be made from a prototype of A, copied to make all on the list, and all objects on the list must be the same type. In other words, if B and C derive from A, then one X can hold a list of As, another can hold a list of Bs and another can hold a list of Cs, but all Xs will also be on a list, and I don't think I could put an X, an X and an X all on the same list, could I? – ThisIsMe Oct 05 '21 at 16:54
  • @ThisIsMe _"but I need to restrict it to only subtypes of A, which I don't think I can do with a template (can I?). "_ Of course you can, it's possible to use compile time checks to prevent inappropriate interfaces. – πάντα ῥεῖ Oct 05 '21 at 16:57
  • 1
    @ThisIsMe Yes, you can constrain template types to only be derived from a particular type. The issue you'll find if that if you have a `base*`, you will only get a `base&` from it when you dereference it, as that is the static type. You wont be able to copy the derived object that it actually points to because that information is not something you can get just from the pointer. This is why we have the clone idiom. It solves this whole issue with the small requirement that the derived class adds one extra virtual function that needs to overridden. – NathanOliver Oct 05 '21 at 16:59

1 Answers1

-3

use memcpy it copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.REFERENCE

memcpy(p2, p1, 100 * sizeof(int));

and of course you can do this

int A = 4;
int* pointer1 = &A;
int* pointer2 = pointer1;
  • That's the totally wrong solution in c++. `memcpy()` won't work properly for complex c++ classes with pointer members. – πάντα ῥεῖ Oct 05 '21 at 16:53
  • OP does not know the true type of the source so `sizeof` is not going to work. – Richard Critten Oct 05 '21 at 16:58
  • But I could do something like this, right?: – ThisIsMe Oct 05 '21 at 17:02
  • A* a = param_a; A* b = new A(); memcpy(b, a, sizeof(*a)); That might work, except that since b is only allocated to hold the size of A, I might get a memory access error or something. I wonder if the template example can be used from the bottom of this page: https://stackoverflow.com/questions/5148706/copying-a-polymorphic-object-in-c But only if I use a decltype in the template call, like so: A* a = param_a; A* b = clone(a); Would that work? I've never used decltype before. – ThisIsMe Oct 05 '21 at 17:08
  • *But I could do something like this, right?* You could, and it can look like it worked, but if it did, it's only because of dumb luck. Never count on luck. – user4581301 Oct 05 '21 at 17:28
  • I'm not trying to count on luck; I just wanted to know if that would solve the problem or not. In any case, I don't see why I should have to override a function in every derived type, because how is that a polymorphic use of derived types? They should work by default. – ThisIsMe Oct 05 '21 at 17:53
  • You don't have to override everything, but everything that could be overridden needs to be in the base class and marked virtual. The point of polymorphism is the user should not know exactly what type they hold. The user invokes a method and that method does the right thing for the unknown class. In order to use `memcpy` the user has to A) know the actual class being copied and B) know that the class holds no resources that require special copying logic, such as [owned pointers](https://stackoverflow.com/questions/49024982), or cannot be copied, like a mutex. – user4581301 Oct 05 '21 at 18:38
  • Well perhaps I misspoke, but how about the point of code reusability, which is so that I don't have to keep rewriting the same function a hundred times (and I'm actually not exaggerating) when I should just be able to copy arbitrary objects, as long as they have a compatible base. – ThisIsMe Oct 05 '21 at 19:09
  • Actually though, it just occurred to me, what if I change it around like this?: A* a = param_a; decltype(*a) temp = *a; decltype(a) b = new A(); *b = temp; Might that accomplish the goal? But then I realized that the "new A()" might cause a problem, but can I do a "new decltype(*a)()" or something like that? – ThisIsMe Oct 05 '21 at 19:12
  • `decltype` will only return the known type `A` or `A*`, not the child type. All of this stuff needs to be resolved at compile time, so there's no way it can make decisions based on runtime information. – user4581301 Oct 05 '21 at 19:35
  • Well that's very disappointing. It seems like every attempt *almost* solves it, but not quite. – ThisIsMe Oct 05 '21 at 20:16
  • This is one of those cases where the quest for speed gets you. Because there would be hidden and not-insignificant overhead in the code that could be automatically generated to do this for you, C++ leaves it up to the programmer to manage that overhead as best suits them. If the objects all have a copy constructor (or don't need one), the `clone` method is pretty simple `A* B::clone() { return new B(*this); }` – user4581301 Oct 05 '21 at 20:24
  • Yeah, that's what I ultimately ended up doing, but I'll have to make very many of them, one for every derived type. I just think there should be a more reusable way to do it. Oh well. – ThisIsMe Oct 06 '21 at 17:00