I just discovered from this Q/A that structs are inheritable in C++ but, is it a good practice, or is it preferable to use classes? In which cases is preferable and in which ones is not?
I have never needed this, but now I have a bunch of messages of different types, but same longitude. I got them in binary in a char array, and I just copy them with memcpy to the struct to fill its fields (I don't know if it is even possible to do it with std::copy).
I guess it would be great to be able to inherit every struct from a base struct with common headers, that is why I searched for this. So a second question would be: if I do this with classes, is it possible to do a memcpy (or std:copy) from a buffer to a class?
Whether you can use a bitwise copy or not has nothing to do with the struct
or class
tag and only depends on whether said struct
or class
is_trivially_copiable
. Whether they are is defined in the Standard (9/6 [class]) and it basically boils down to not having to declare any other special member methods than constructors.
The bitwise copy is then allowed by the Standard in 3.9/2 [basic.types]
For any object (other than a base-class subobject) of trivially copyable type
T
, whether or not the object holds a valid value of typeT
, the underlying bytes (1.7) making up the object can be copied into an array ofchar
orunsigned char
. If the content of the array ofchar
orunsigned char
is copied back into the object, the object shall subsequently hold its original value. [ Example:#define N sizeof(T) char buf[N]; T obj; // obj initialized to its original value std::memcpy(buf, &obj, N); // between these two calls to std::memcpy, // `obj` might be modified std::memcpy(&obj, buf, N); // at this point, each subobject of `obj` // of scalar type holds its original value
—end example ]
Note: a bitwise copy of padding bytes will lead to reports in Valgrind.
Using std::copy
to the same effect:
char const* b = reinterpret_cast<char const*>(&obj);
std::copy(b, b + N, buf);