My first post so please go easy on me!
I know that there\'s no real difference between structs and classes in C++, but a lot of people including me use a struct or class
My simple rule of thumb for structs and classes:
if (data_requires_strict_alignment == TRUE) {
use(struct);
} else {
use(class);
}
That is, if the data you are representing corresponds to some data object that has strict member order and alignment requirements (for example, a data structure exchanged with hardware on the driver level), use a struct. For all other cases, use a class. Classes have so many features and capabilities that structs do not, and in my experiences it is beneficial to use classes whenever possible, even if you are not using any of those additional features at the moment (if nothing else, a data-only class is like a struct with a safer default access level). Reserve structs for those cases when you need the unique properties of a struct; namely, the ability to specify structure members in a precise order and with precise alignment/padding (typically with low-level communication, e.g. drivers) such that you can cast it to a byte array, use memcpy()
on it, etc. If you follow this model, then a class would not be used as a member of a structure (since a class definition does not specify alignment or a predictable value for sizeof(class)
). Likewise, if you are thinking about constructors or operators, use a class.
This rule of thumb also helps make it easier to interface with C code, since structs are used in a manner consistent with C structures.
The only methods I like to put on structs are property-type methods, simple transforms (and, if appropriate for the type, operators), and non-default constructors.
For instance, I might define a RECT
struct as below:
typedef struct tagRECT{
int left;
int top;
int right;
int bottom;
int get_width(){return right - left;}
int get_height(){return bottom - top;}
int set_width(int width){right = left + width; return width;}
int set_height(int height){bottom = top + height; return height;}
} RECT, *PRECT;
The "set" methods return the new value to support assignment chaining in the case that the compiler supports properties as an extension.
For POD types that store complex data, I might include methods that perform simple transformations on that data. An obvious example might be including Rotate, Scale, Shear, and Translate methods on a TransformationMatrix struct.
Really just an extension of the above, if operators make sense for the type, I will add them to a struct. This can be appropriate and necessary to maintain the atomicity of the object. An obvious example is standard arithmetic operators on a Complex struct.
I prefer not to have a default constructor on my structs. I don't want to allocate an array of PODs and suffer the invocation of a thousand (or whatever) default initializations. If memset
initialization won't suffice, I'll provide an Initialize method.
I will, however, provide a non-default constructor on structs. This is especially useful when one or more fields can be inferred from partial construction.
My personal preference is to only use structs if there's no methods at all. If I need to add a method for any reason, it's a class.
I always use structs for 'lumps of data', even if they get decorated with a constructor and sometimes comparison operators, they never get methods added to them (not even get/set methods).
I think this shows the intent of the type - a struct is just data to be operated on by other things.
Consistency is most important. The point of conventions are to give a common point of reference for all those reading your code in the future.
Personally, I avoid structs if I feel I need the functionality of a class.
AKA: "plain old data" approach.
Look at your project and set a standard, or adhere to the one already there.
Though, I suggest you try to avoid inheritence, especially if all the struct is doing is holding POD. Nothing worse then tracing a bunch of super classes for an integer or char.
I use struct whenever I want to use data member as interface of the object. I'd change the struct to a class, whenever there is a need to add a private section.