Hello, my name is Jonathan Boccara. I'm your host on Fluent C++. I have been a C++ developer for 6 years, working for Murex which is a major software editor in the finance industry. My focus is on C++ and particularly how to write expressive code. I'm happy to take your feedback, don't hesitate to drop a comment on a post, follow me or get in touch directly !
Jonathan Boccara's blog
“Should I use a
struct or a
Such is the question many C++ programmers ask themselves, or ask around to more experienced co-workers, when designing their code.
There is sometimes a cloud of misconception about what the difference between
class technically is, particularly amongst the youngest developers. And once we get to understand the technical difference, some degree of uncertainty often remains about which one to use in a given context. Sometimes developers even disagree about which is the more appropriate in their code.
Let’s start by clearing up the situation, by stating the technical difference between
class, and then propose rules to choose between the two, by looking at what the C++ Core Guidelines written by the Jedis of C++ have to say about it.
In terms of language, except one little detail, there is no difference between
class. Contrary to what younger developers, or people coming from C believe at first, a
struct can have constructors, methods (even virtual ones), public, private and protected members, use inheritance, be templated… just like a
The only difference is if you don’t specify the visibility (public, private or protected) of the members, they will be public in the
struct and private in the
class. And the visibility by default goes just a little further than members: for inheritance if you don’t specify anything then the
struct will inherit publicly from its base class:
struct T : Base // same thing as "struct T : public Base"
class will do private inheritance:
class T : Base // same thing as "class T : private Base"
That’s it. No other difference.
Once we get past this language precision, the following question arises: if
class are so similar, when should I use one or the other?
class: what you express by using them
The difference that really matters between
class boils down to one thing: convention. There are some conventions out there that are fairly widespread and that follow a certain logic. Following these conventions gives you a way to express your intentions in code when designing a type, because as we’ll see in a moment, implementing it as a
struct doesn’t convey the same message as implementing it as a
In a word, a
struct is a bundle. A
struct is several related elements that needed to be tied up together in a certain context. Such a context can be passing a restricted number of arguments to a function:
void distance(Point p1, Point p2);
Although it’s a bundle,
struct can be used to effectively raise the level of abstraction in order to improve the code: in the above example, the
distance function expects Points rather than doubles. And on the top of this, the
struct also has the benefit of logically grouping them together.
Another context is returning several values from a function. Before C++17 and structured bindings, returning a
struct containing those values is the most explicit solution. Have a look at Making your functions functional for more about making function interfaces clearer.
In two words, a class can do things. A class has responsibilities. These responsibilities can be quite simple, like retrieving data that the class may even contain itself. For this reason, you want to use the term
class when you are modelling a concept (that has an existence in the business domain or not), the concept of a object that can perform actions.
Contrary to a
struct, a class is made to offer an interface, that has some degree of separation from its implementation. A
class is not just there to store data. In fact a user of a class is not supposed to know what data the class is storing, or if it contains any data at all for that matter. All he cares about is its responsibilities, expressed via its interface.
class raise the level of abstraction between interface and implementation even more than a
Sometimes a type that was initially implemented as a
struct ends up turning into a
class. This happens when you realize the various bits that were bundled turn out to form a higher level concept when they are considered together, or have a stronger relation than what was perceived initially.
This is were invariants come into play. An invariant is a relation between the data members of a class that must hold true for the methods to work correctly. For example, a
std::string can hold a
char* and a
size in its implementation (well at least conceptually, since modern string implementations are more complex than that due to optimizations). Then an invariant is that the number of characters in the allocated
char buffer must match the value in the
size member. Another invariant is that the
char* is initialized and points to valid memory.
Invariants are set into place by the constructor of the
class and the methods make the assumption that all the invariants hold true when they are called, and ensure they remain true when they finish. This can be a tacit agreement, or, as has been discussed for standardization, such pre-conditions and post-conditions in methods could one day be explicitly stated in code, and checked at run-time.
Finally a simple rule of thumb for choosing between
class is to go for
class whenever there is at least one private member in the structure. Indeed, this suggests that there are implementation details that are to be hidden by an interface, which is the purpose of a class.
The above has been inspired by the C++ Core Guideline (which is a great read by the way), in particular the following: