Struct inheritance vs class inheritance in C++

2019-04-10 04:11发布

问题:

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?

回答1:

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 type T, the underlying bytes (1.7) making up the object can be copied into an array of char or unsigned char. If the content of the array of char or unsigned 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);


回答2:

The only difference between struct and class is the default access modifier to its members. In struct it's public and in class it's private (until stated otherwise). Besides that struct and class are identical in C++. Sometimes structs are prefered for PDO (Plain Data Objects) over classes for readability but that's really up to a coding convention.