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 to show intent - structs for grouping "plain old data" and classes for encapsulated data that has meaningful operations.
Now, that's fine but at what point do you start to think that something isn't just a struct anymore and should become a class?
Things I think are reasonable for structs to have:
- constructors with simple initialisation code only.
- serialization code such as stream insertion / extraction operators.
Things I'm not so sure about, but would probably do:
- comparison operators
- Simple transformation functions - for example byteswapping all the members after receiving data from an external source.
I don't think structs should have:
- dynamic memory allocation.
- destructor.
- complex member functions.
Where do the boundaries lie???
Also, is it reasonable to have class instances as members of a struct? e.g.
class C {private: int hiddenData; public: void DoSomething();};
struct S {int a; float b; C c; };
S s; s.c.DoSomething();
Remember, I'm not on about what you CAN do with C++, I'm interested in what you SHOULD do when designing good software.
Thoughts?
I use classes and encapsulation when I need to maintain invariants and data integrity. If you have no invariants, and the data really is just a bucket of items, it has always been fine in our shop to use struct even if you add fancy helper constructors or functions. However the more you do decorate it, that should make you stop and think that maybe it should be a class.
If you do have to be POD compatible (for say interfacing to C code) you do still need to use struct. However you can wrap this struct in a class and expose it with a get() function for interfacing with C API's. Or create a helper function to return a proper POD struct from your class.
I might be in the minority, but I use
struct
s to mean one thing, "the order of the bits matters". Anything that must be serialized to disk or network, or has to be compatible with some third party library and needs to be in the right order, Or if it's doing some kind of bit field magic as a processor specific optimization, that always goes into astruct
. Rearranging the fields in astruct
, therefore, always has some kind of consequences and should be carefully thought out.class
es, however, have fields that are only semantically meaningful. If for some reason I or someone else wants to rearrange or modify the data members of aclass
, this can happen pretty freely.IMHO, this differentiation is a misunderstanding but it's well understood why it is used like that. It is based on traditional conventions and built-in feeling about class vs struct. I'd follow Marshall Cline's suggestion:
7.8 What's the difference between the keywords struct and class?
Personally, I (over)use
struct
keyword formetafunctions
This is purely a matter of style, and what is right or wrong will be dictated by your shop. Sometimes the decision will be to make no decision but, to paraphrase Rush, they still will have made a choice.
As a rule of thumb I will generally use structs for simpler datatypes rangin from PODs to objects that have member simple functions. But there is no bright line, and once I define a struct I will not normally go back and change it to a class just because I added more functionality. I see no value in that.
Another common use of structs is for template stuff and local RAII or functor classes. These are one-off bits of code that are closer to functions than they are to whole classes, and requiring the extra
public:
declaration is just silly. If you look at boost, you'll see a lot of stuff like this:It's clearly not a POD (in fact it doesn't hold any data at all). In other cases you can have RAII class that consist of only a constructor/desctructor:
Functor classes would offer the same argument:
I'd say there's no one feature of C++ that implies you should use a class instead of a struct (except maybe virtual functions). It's all about what interface you want to present - use a struct if you are ok with everything being public. If you find you are wanting to add
private:
sections, that a good sign you really want a class instead of a struct.From reading through some STL source code which ships with Visual Studio, it appears that one criteria in use is are things "mostly public" (start with a struct) or "mostly private" (start with a class)?
In a similar vein, if what you write near the top (maybe because it's important) of your class is public, then go with struct. On the other hand, if you list member data first use class.