4

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?

3
  • 2
    In C++ structures and classes are almost the same, the only difference being that for struct the default visibility is public while for classes it's private. Commented Oct 23, 2012 at 7:10
  • 1
    What do you plan to put in the base struct? Commented Oct 23, 2012 at 7:15
  • 2
    There is one more difference between class and struct, which affects inheritance specifically: The default mode of inheritance is private with class, but public with struct. So when you do struct D : A, this will be the same as struct D : public A. But that should not stop you from using inheritance with struct of course. Commented Oct 23, 2012 at 7:21

2 Answers 2

5

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);
Sign up to request clarification or add additional context in comments.

5 Comments

Ok, so it is possible to do it with classes. Are padding bytes the reason of using #pragma pack? And one more question: could you edit your answer and add the same code using std:copy? I know compiler will most likely change if back to memcpy, but I'm curious about how to call std:copy for this task
@RomanRdgz: #pragma pack will indeed remove padding bytes (well pack(1) will, pack(2) may not) at the cost of correctness. However, padding bytes are introduced to respect alignment constraints on the types, so removing them equates to violating those constraints. On x86, the code will work, but access to the mis-aligned parts will be slower (the CPU does extra work); on some architectures, a hardware exception may be raised (crashing the program). Do not use it.
Ok I see, so with a pointer to the class it is possible to use std::copy. Thanks
About the pack, the problem is that my buffer contains n bits representing something, the following m bits represent another thing... I need bit level when copying to the struct, so I need to pack. If I can't use (or shouldn't) that pragma, how would you suggest doing it?
@RomanRdgz: Two options. The portable and evolutive one is to create a routine that read from the char array and set each field of the structure appropriately (and back). This is typically called serialization. The optimized one, which is highly-platform dependent and require a new structure for each new version of the protocol, is to use bit fields.
1

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.

6 Comments

Is 'PDO' the same as 'POD' (Plain Old Data)?
also struct has public inheritance by default. struct B : A is equivalent with struct B : public A (where A is a struct or a class)
Sure, I already know that, but if structs are used for PDO just for convention, and using classes is as good solution as structs, then is it possible to use memcpy and std:cpy over a class just as I can do over a struct?
@xtofl yea, it's also a convention issue :)
@icepack: POD has the advantage of being the acronym used in the C++ standard. Anyway, what you mean is clear.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.