How to Choose Between Struct or Class

“Should I use a struct , or a class ?”

Such is the question we sometimes ask ourselves when creating a new type.

What’s the difference between struct and class in C++? How to to choose one or the other?

This is the question we tackle in this week’s video:

Transcript of the video:

What’s the difference between a struct and a class ? And more importantly, when should we use one or the other? That’s what we’re talking about today on Fluent C++.

Let’s start by the difference between a struct and a class . The legal difference: there is no difference at all.

Well, that’s a lie but a very small and insignificant one. The only technical difference is that if you don’t say anything about scoping, what’s in the struct is going to be public whereas what’s in a class is going to be private .

It also goes for inheritance: if a struct inherits from something else and you don’t specify if is is a public or private inheritance:

struct Derived : Base { }; 1 2 3 struct Derived : Base { } ;

the inheritance is public . And for a class it would be private .

Of course, you can have public and private members and inheritance if you just write it, in either struct or class .

Apart from that there is absolutely no difference. You can do anything in struct that you would do in class : a struct can have inheritance, public , private , protected members, virtual methods, templates, overloads, SFINAE, what have you.

So how do we make a choice whether to use a struct or a class ? It comes down to convention. Choosing between struct or class out of convention allows to express your intent when you create a new type.

The convention for a struct is: a struct is a bundle. A struct is just there to stitch things together. Several objects, like several objects that come out of a function for example. You can then use struct to express that there is no unity and that it’s just a bundle.

Actually, there’s a question you may ask: what’s the difference between a struct and a pair (or a tuple ) in that regard? Indeed, the pair (or tuple ) also puts things togethers in a bundle.

The difference between a struct and a pair (or tuple ) is that the struct has a name. So if there’s a name that makes sense over the bundle of things you’re putting together, you’d rather use a struct . If there’s absolutely no name and those things only happen to be together at the same place and time, then you’d use a pair or tuple .

In this regard, the struct rises the level of abstraction of the bundle a little, by giving it a name. And that names characterizes what that bundle represents.

Now about class . A class does things, that’s the essence of a class . It has responsibilities, which are represented by the methods of its interface. You don’t care about what data there is in the class when you’re a user of that class . Actually it may not even have any data at all and that doesn’t matter. What matters is its interface.

So a class rises the level of abstraction much more than a struct does, because it hides an implementation behind an interface that describes what this class can do.

Another thing that a class can do is implementing invariants. An invariant is a property that must hold true all the time in a class from the perspective of the client of that class. For example, say in a string, you have a buffer than contains the characters populating the string, and also a size in the string. And from the perspective of the user of that string, you want that the size corresponds to the actual number of characters in the string.

The contract of a class is the constructor puts those invariant in place, and all the methods assume that those invariants are verified.

A struct doesn’t do that at all: a struct is a bundle where you can see right through it, and there is no relation between its members.

Today, that’s pretty much all we have to describe a type: struct or class . But in a distant future we may have more than that, with the metaclasses proposal. But that’s a topic for another video.

We’re going to end this video by reading the titles of 4 of the C++ Core Guidelines from which I took inspiration to structure this video.

Organize related data into structures ( struct s or class es)

Use class if the class has an invariant; use struct if the data members can vary independently

Represent the distinction between an interface and an implementation using a class

Use class rather than struct if any member is non-public

If you like this video feel free to share it, subscribe to the Fluent C++ channel, and put a thumb up!

Thanks, and I see you next time.

Related posts:

The right question for the right name

The metaclasses proposal in less than 5 minutes (next week)

Share this post! Don't want to miss out ?