Why might I want to use a struct rather than a class if the only difference between the two is a struct defaults members to public while a class defaults to private? I typically only utilize classes and I'm starting to wonder if I'm missing out on using structs.
It's up to you.
If I'm writing internal classes for a program, I'll probably use structs, since there's no point in denying myself access to my own data. That just leads to ridiculous and costly interfaces.
If you're writing something more like a library, it's probably best to use classes to not allow the user to mess with the data.
You are right, there is no difference (anymore). There used to be a difference though, and for backwards compatibility the C++ language had to keep both keywords.
There is no rhyme or reason to prefer one or the other; in the struct case you might end up typing an extra "private:" line whereas in the class case you'll end up writing an extra "public:" line.
My own personal coding standard says to use "struct" for so-called (and poorly named :)) value classes, and "class" for everything else. But that is just a personal preference and has no benefits one way or the other.
No, structdefaults to public access and inheritance, but you can change that with the private and protected keywords just as in any other class.
Some people use struct to indicate that the class is a POD, or Plain Old Data, object (no methods, inheritance, etc).
Personally, I use whichever is most convenient and/or easiest to read. If I want to derive some minor modification from another class, or just create some simple class, I'll just use struct, since it saves typing/clutter.
Here's a side-by-side example of a little stream that simply discards everything it gets, defined with struct on the left and class on the right.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
struct null_stream: std::ostream class null_stream: public std::ostream
{ {
struct nullbuf: std::streambuf public:
{ class nullbuf: public std::streambuf
int overflow( int c ) {
{ public:
return traits_type::not_eof( c ); int overflow( int c )
} {
} return traits_type::not_eof( c );
m_sbuf; }
}
null_stream(): m_sbuf;
std::ios( &m_sbuf ),
std::ostream( &m_sbuf ) null_stream():
{ } std::ios( &m_sbuf ),
}; std::ostream( &m_sbuf )
{ }
};