This short article reminds that C++ structs are classes too.

Class and struct

There are two major ways of building new types. One is by putting together multiple pieces of the same type. These are arrays.

The other one is by putting together pieces of different types. There are two keywords in C++ that allows us to do that: class and struct.

The classic usage is to use class for C++ classes and struct for interoperability with C APIs. However the only real difference between them is the default visibility of members, which is private for class and it is public for struct.

Both struct and class create C++ classes. It is perfectly good to use struct for classes, for example for small classes with all public members, as we’ve seen for example in the slim RAII variant.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct file
{
  FILE * p;

  explicit file(FILE * x) noexcept :
    p{ x }
  {
  }

  ~file()
  {
    if (p)
    {
      fclose(p);
    }
  }
};

If we were to use the class keyword, we would needed an extra line to change visibility to public:

1
2
3
4
5
class file
{
public:
  ...
};

A good pattern for a C++ class that stores various pieces of data together is a struct that uses member variable initialization.

1
2
3
4
5
6
7
struct data
{
  int value{};
  int answer{ 42 };
  bool valid_answer{};
  std::string reason{};
};

This eliminates the need to write a constructor to initialize the member variables. Also note that only fields where the default value was not desired are initialized (default value for int-types is 0, false for bool and nullptr for pointers).

Once initialized with data (e.g. from a stream), pass it by const reference to make its fields read only.

Summary

Use struct to convey the message: “this is a class with (mostly) public members”.