Notes on C++ struct


As a first approximation, we may say that a struct is a class with no methods.



Here is an example that illustrates this:

Java

C++

public class Book{
  public int nPages;
  public double price
}
struct Book{
  int nPages;
  double price;
};

Note the semi-colon at the end of the C++ struct!

Here is how you can compute with a Java class or C++ struct:

Java

C++

Book myBook = new Book();
myBook.nPages = 321;
myBook.price = 123.45;
Book myBook;
myBook.nPages = 321;
myBook.price = 123.45;

Observe that in the C++ version, there is no reference to new.  While the code segments above use the same DOT syntax, there is not a complete parallelism between the Java and C++ versions.  The difference between them is related to memory allocation, as we see next.

When we write in C++

struct Book{
  int nPages;
  double price;
};
Book myBook;
myBook.nPages = 321;
myBook.price = 123.45;

the compiler will allocate space for myBook.

What about dynamic storage allocation?  Here are equivalent ways to handle dynamic data in C++:

Book *myBook;
myBook = new Book;
myBook->nPages = 123;
myBook->price  = 123.45;
//...
delete myBook;
Book *myBook;
myBook = new Book;
(*myBook).nPages = 123;
(*myBook).price   = 123.45;
//...
delete myBook;

These blocks of code accomplish exactly the same thing.  Their only difference is in the way that the fields (nPages and price) of the dynamically allocated struct are referenced.

Note that the compiler will not let you use the simple DOT notation to reference the fields of Book.  You cannot write myBook.nPages = 123 or myBook.price = 123.45;.

As it turns out, dynamically allocated structs are analogous to Java classes with no methods.  The following code segements behave in a similar way:

Java

C++

Book myBook = new Book();
myBook.nPages = 321;
myBook.price = 123.45;
Book *myBook;
myBook = new Book;
myBook->nPages = 123;
myBook->price  = 123.45;
//...
delete myBook;

Notice that the Java code does not take care of deleting memory associated with myBook.  It doesn't need to.  The Java virtual machine automatically deletes memory that is no longer used.  The methodology is called garbage collectionJava has garbage collection, C++ does not.



The difference between structs and classes

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. Not quite so.



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++ struct s 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 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. 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.

In C++, structs also support class properties such as inheritance, friend declarations, etc.

Conclusion

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.