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

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

  1. "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.)
  2. "Is struct faster than class?" β€” no. Identical code, identical performance; only the default access differs.
  3. "When would you deliberately choose struct?" β€” passive aggregates (points, colors, DTOs), and interop contexts where C-compatible layout matters.
  4. "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.
  5. "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

  1. Type the PointS/PointC proof above and read the exact compiler error for c.x = 1.
  2. Flip PointC to struct and confirm the error disappears β€” same code, one keyword.
  3. Write class Temperature with a private celsius and a set(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).