struct vs class in C++: the only real difference
Short answer: they are the same thing with one default flipped: members of a struct are public by default; members of a class are private by default. Same for inheritance defaults. Everything else β methods, constructors, inheritance, templates β works identically in both.
Heads-up: our in-browser engine covers the teaching core and doesn't support user-defined struct/class yet, so the snippets here are for your desktop compiler. The concepts are core interview material, so read on.
Proof: one keyword swap changes access
struct PointS {
int x; // public (struct default)
int y;
};
class PointC {
int x; // private (class default)
int y;
};
int main() {
PointS s;
s.x = 1; // fine β x is public
PointC c;
c.x = 1; // ERROR: 'int PointC::x' is private
}
That's the entire mechanical difference. Change class to struct in the example and the error disappears. Nothing else about the two keywords differs.
Both can do everything
// A struct with methods, a constructor and private members: perfectly legal
struct BankAccount {
private:
double balance = 0;
public:
explicit BankAccount(double start) : balance(start) {}
void deposit(double amount) {
if (amount > 0) balance += amount;
}
double getBalance() const { return balance; }
};
// A class used as a plain data bundle: also legal, just unconventional
class Config {
public:
int width;
int height;
};
So if they're interchangeable, why do both exist? History and convention. C++ inherited struct from C (where it can only hold data), and added class for object-oriented programming β then made them the same construct with different defaults.
The convention real codebases follow
struct= passive data bundle. If the whole point is "these values travel together" and any value is valid at any time β a 2D point, an RGB color, a config record β usestructwith public members.class= things with rules. If certain combinations of values are invalid, or operations must maintain invariants ("balance never goes negative"), useclass: make data private, expose methods that enforce the rules.
The smell test: would any random assignment of public members create a nonsense object? Yes β class. No β struct.
The second default people forget: inheritance
struct DerivedS : Base { }; // inherits PUBLICly by default
class DerivedC : Base { }; // inherits PRIVATEly by default
Same keyword, same flipped default β for inheritance instead of members. In practice you should always write the access level explicitly in inheritance anyway, but interviewers love this detail.
Interview questions on this theme
- "What's the difference between struct and class in C++?" β default member access and default inheritance access; nothing else. (In C, the answer is totally different: struct can't have methods at all.)
- "Is struct faster than class?" β no. Identical code, identical performance; only the default access differs.
- "When would you deliberately choose struct?" β passive aggregates (points, colors, DTOs), and interop contexts where C-compatible layout matters.
- "What's an aggregate?" β roughly: a struct with no user constructors/private members, initializable with braces:
Point p {1, 2};. Classes with invariants can't be aggregates, by design. - "Why make members private at all?" β so the object can guarantee its own rules (invariants); public data means anyone can break them and you can never add validation later without breaking every caller.
Practice on your desktop compiler
- Type the
PointS/PointCproof above and read the exact compiler error forc.x = 1. - Flip
PointCtostructand confirm the error disappears β same code, one keyword. - Write
class Temperaturewith a privatecelsiusand aset(double)that rejects below β273.15 β that's an invariant, the thing structs-with-public-data can't protect.
Related: pass by value vs pointer vs reference (how these objects travel into functions), stack vs heap (where they live), 15 beginner interview questions (this is Q14 there).