1

I have a class which stores a pointer to a data chunk and the size of the data. It implements operations like 'head', 'tail',... but it is irrelevant from the question's point of view. I use this instead of std::vector where I do not want deep copying. However I need to copy the data sometimes, so I have a member function 'duplicate' to do it.

struct ByteArray {
    char* data;
    int size;
    ByteArray(char* data, int size) : data(data), size(size) {}
    ByteArray duplicate() const {
        char *duplicatedData = new char[size];
        memcpy(duplicatedData, data, size);
        return ByteArray(duplicatedData, size);
    }
};

Now I have a derived class - extending the previous class, where I need a duplicate method too, which calls the base class' duplicate. I have managed to solve it by casting both objects to the base class, but I suspect that this is not the best solution. Am I missing a more obvious solution? Also is this class the right solution to the original problem (not having deep copy) or there is standard solution what I'm not aware of?

struct Foo : ByteArray
{
    int bar;
    ... // more members
    Foo(ByteArray &bytes, int bar) : ByteArray(bytes), bar(bar) {}
    Foo duplicate() const {
        Foo dup = *this;
        static_cast<ByteArray&>(dup) = ByteArray::duplicate();
        return dup;
    }
};
simon
  • 1,210
  • 12
  • 26
  • Have you read this: http://stackoverflow.com/questions/357307/how-to-call-a-parent-class-function-from-derived-class-function – NathanOliver May 27 '15 at 13:11
  • Sorry, I see. Due to several edits the call of the base method remained in this form. I'm aware of the syntax of calling base method (described in the linked answer), but I'm more concerned with the assignment to the object casted to base class. (I'll edit the question now) – simon May 27 '15 at 13:19

2 Answers2

1

If you changed your Foo constructor to take a ByteArray by const reference instead, duplicate() would be pretty straightforward:

Foo duplicate() const {
    return Foo(ByteArray::duplicate(), bar);
}

As-is, you can still do it the same way, just need an extra line:

Foo duplicate() const {
    ByteArray ba = ByteArray::duplicate();
    return Foo(ba, bar);
}
Barry
  • 286,269
  • 29
  • 621
  • 977
0

How about something like this then...

#include <cstring>
#include <iostream>

using namespace std;

struct ByteArray {
  char* data;
  int size;
  ByteArray(char* data, int size) : data(data), size(size) {}
  void duplicate(ByteArray &toCopy) const {
    cout<<"Byte array duplicate."<<endl;
    char *data = new char[toCopy.size];
    memcpy(data, toCopy.data, size);
  }
};

struct Foo : ByteArray
{
  int bar;
  Foo(ByteArray &bytes, int bar) : ByteArray(bytes), bar(bar) {}
  void duplicate(Foo &toCopy) const {
    cout<<"Foo duplicate."<<endl;
    ByteArray::duplicate(toCopy);
  }
};

int main(){
  char* str = "some data";
  char* null = "";
  ByteArray barr (str, 9);
  ByteArray barr2 = barr;
  barr2.duplicate(barr);

  Foo farr (barr, 2);
  Foo farr2 = farr;
  farr2.duplicate(farr);

}
Christian Sarofeen
  • 2,202
  • 11
  • 18
  • Yes, but I have several additional members in the actual code's Foo class unfortunately. – simon May 27 '15 at 13:24
  • Also, won't this be a stack overflow not calling the base, but the derived duplicate()? – simon May 27 '15 at 13:25
  • I fixed it. It demonstrates the calls now too. – Christian Sarofeen May 27 '15 at 13:29
  • I suppose, but I would rather have only one function call than an assignment with a function call where the class used. – simon May 27 '15 at 13:42
  • So you want to be able to use both `foo2=foo.duplicate();` and `foo3=foo;` first meaning deep copy and second meaning shallow copy? – Christian Sarofeen May 27 '15 at 13:50
  • I think it starts to be come much more difficult. You can check out... http://www.learncpp.com/cpp-tutorial/912-shallow-vs-deep-copying/ and http://stackoverflow.com/questions/7297024/call-default-copy-constructor-from-within-overloaded-copy-constructor – Christian Sarofeen May 27 '15 at 13:55