Updated New Zealand edition
Latest
Dev Notes · Archive

The difference between structs and classes

From the archive
C++ note
A close-up view of a vintage Adler typewriter keyboard
Photo: Maksym Kozlenko / Wikimedia Commons, CC BY-SA 4.0
From the carcino.gen.nz archive. This C++ note was written for the original site and is kept as published; newer systems and toolchains may behave differently.

Quick explanation:

The only difference between structs and classes in C++ is that the members of a struct have public visibility by default, and the members of a class have private visibility by default.

There is a popular misconception that C++ structs are just the same as C structs, and that therefore there are many other differences between structs and classes in C++, like, say, that structs don't have constructors, member methods, or inheritance. Nuh-uh.

A lot of people don't believe me when I tell them about this. You can either a) try it yourself, or b) keep reading as I repeat this one fact several times, using different words.

Table of contents 1. C structs... 2. ...are not the same as C++ structs. 3. Conclusion

C structs...

C structs are pretty simple beasts. They contain only primitive data types as members, all of which are visible to anything that can access the struct definition, they have no methods and no constructors or destructors, and there's no such thing as inheritance.

...are not the same as C++ structs.

However, C++ structs are not just the same as C structs. It's true that C++ is fully backwards compatible with C struct declarations; any legal C struct definition will compile, and will define exactly the same thing as it did in C.

But in C++, structs can do a lot, lot more. In fact, C++ structs are exactly the same as C++ classes, in all but one respect. If I declare members in a C++ struct, like so:

struct Foo
{
    int bar;
    char* baz;
};

- then the members of the struct, in this case bar and baz, will be given public visibility by default, which means that the following function:

Foo makeFoo()
{
    Foo temp;
    temp.bar = 1;
    temp.baz = "test";
    return temp;
}

- would compile just fine. However, if I instead defined a class, like so:

class Foo
{
    int bar;
    char* baz;
};

- then now my function won't compile, because the members of the class are given private visibility by default; I'll get errors like

`int Foo::bar' is private

and

`char*Foo::baz' is private

as usual.

Of course, if you want non-member functions to be able to set the members of the class directly, the fix to the class is simple - just declare public visibility for the members:

class Foo
{
public:
    int bar;
    char* baz;
};

But, surprise surprise, you can change the visibility of the members of the struct too, for example, making them private:

struct Foo
{
private:
    int bar;
    char* baz;
};

Now, just as for our original class example, this struct definition compiles fine but the non-member function that tries to access its members won't.

Of course, setting member visibility is not much use if you don't have all the other things that come with classes - in particular, member functions, constructors, and destructors. And lo, C++ has them for structs. Try the following:

#include <iostream>
using namespace std;
struct Example
{
    int a;
    Example(int b);
    void printA();
};
Example::Example(int b)
{
    a = b;
}
void Example::printA()
{
    cout << "a = " << a;
}

Compiles just fine.

Disbelieving readers can try out inheritance, friend declarations, etc. etc. if they doubt that the same applies to them.

Conclusion

So, one more time: in C++, a struct is identical to a class except that the members of a struct have public visibility by default, but the members of a class have private visibility by default.

Correcting all the people who keep teaching otherwise is left as an exercise to the reader.

Newer on Dev Notes