Language[lang]
C++ struct vs class: the only two differences
- Section
- Language [lang]
- Standard
- C++17
- Compilers
- MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2, Clang 23.1 (libc++)
- Published
- Length
- 7 min read
In this answer8 clauses
- 1What is the difference between a struct and a class in C++?
- 2Does the default also apply to inheritance?
- 3What is the same in a struct and a class?
- 4When should you use a struct and when a class?
- 5Is a struct faster, smaller or a value type?
- 6What is the difference between a C struct and a C++ struct?
- 7Can you mix struct and class in declarations and templates?
- 8Struct or class: which should you write?
Abstract
C++ struct vs class comes down to two defaults: a struct’s members and base classes are public unless you say otherwise, and a class’s are private. Both can have constructors, member functions, private members, inheritance and virtual functions. By convention, write struct for plain data whose members can each take any value, and class for a type that keeps a rule about its data.

C++ struct vs class comes down to two defaults: in a struct, members and base classes are public unless you say otherwise; in a class, they are private. Nothing else differs: both can have constructors, member functions, inheritance and virtual functions. By convention, write struct for plain data and class for a type that protects its data.
Both keywords in one whole program:
#include <iostream>
struct Point {
int x = 0; // public: struct members are by default
int y = 0;
};
class Thermostat {
int target = 20; // private: class members are by default
public:
void set(int t) { target = t; }
int get() const { return target; }
};
int main() {
Point p;
p.x = 3; // fine: code outside reaches x directly
p.y = 4;
std::cout << "Point: " << p.x << ", " << p.y << '\n';
Thermostat hall;
hall.set(21); // only through what the class made public
std::cout << "Thermostat: " << hall.get() << '\n';
}— end example]
It printed Point: 3, 4 and Thermostat: 21. The samples are C++17, built with MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2 and Clang 23.1 (libc++), and all four printed the same. Nothing here needs a newer standard; Since When lists what each one added. How to write each kind of type is in struct in C++ and C++ class.
What is the difference between a struct and a class in C++?
The default access, for members and for base classes, and nothing else. cppreference’s class declaration page puts it in one sentence: the two keywords “are identical except for the default member access and the default base class access.”
| Default access | struct |
class |
|---|---|---|
| Members | public | private |
| Base classes | public | private |

Declare Point with class instead, and the line that set x stops compiling:
class Point {
int x = 0;
int y = 0;
};
int main() {
Point p;
p.x = 3; // error: x is private in a class
}— end example]
All four compilers reject it. Clang said:
error: 'x' is a private member of 'Point'
note: implicitly declared private here— end example]
“Implicitly” is the default at work: nobody wrote private:. Write public: above the members, or keep struct, and the line compiles.
Does the default also apply to inheritance?
Yes. A struct inherits publicly unless you say otherwise, and a class privately ([class.access.base]). Public inheritance lets code outside call the base’s members through the derived type and use it where a Base is expected; a class gets that only when you write public before the base:
struct Base {
void hello() const { std::cout << "hello\n"; }
};
struct Loud : Base {}; // struct: inherits publicly by default
class Quiet : public Base {}; // class: write public to get the same
int main() {
Loud loud;
loud.hello(); // Base's member, through a Loud
const Base& b1 = loud; // a Loud is a Base to code outside
b1.hello();
Quiet quiet;
quiet.hello();
const Base& b2 = quiet;
b2.hello();
}— end example]
It printed hello four times. Leave out the public, and the call through a Quiet fails:
class Quiet : Base {}; // class: inherits privately by default
int main() {
Quiet quiet;
quiet.hello(); // error: Base is a private base
}— end example]
MSVC says it plainest:
error C2247: 'Base::hello' not accessible because 'Quiet' uses 'private' to inherit from 'Base'— end example]
Binding a const Base& to a Quiet is rejected too. The default follows the keyword of the type being defined, not of its base: Base here is a struct, and Quiet still inherits privately. Inheritance in C++ covers what public, protected and private inheritance each do.
What is the same in a struct and a class?
Everything else. Both keywords allow:
- constructors and a destructor
- member functions, virtual ones included
public:,protected:andprivate:sections- base classes
- templates
With public: written in, a class matches a struct with the same members. A is a struct, B a class with public:, and each static_assert, a check the compiler runs while compiling, compares them:
struct A {
int x;
double y;
};
class B {
public:
int x;
double y;
};
static_assert(sizeof(A) == sizeof(B));
static_assert(offsetof(A, y) == offsetof(B, y));
static_assert(std::is_class_v<A> && std::is_class_v<B>);
static_assert(std::is_aggregate_v<A> && std::is_aggregate_v<B>);
static_assert(std::is_standard_layout_v<A>
&& std::is_standard_layout_v<B>);— end example]
Every assert passed on all four compilers, and each printed sizeof: A 16, B 16 (all four targets were x86-64). To the standard, struct and class both define a class, so is_class_v is true for both. Both are aggregates, types you can fill member by member with braces: A a{1, 2.5}; and B b{1, 2.5}; both worked.
The other way round, a Thermostat declared as a struct with a constructor, a virtual function and a private: member compiled on all four and printed Thermostat (a struct): 21.
When should you use a struct and when a class?
Use struct when each member can take any value on its own (a point, a color, a record), and class when the type keeps a rule about its data or has any member that is not public.
The C++ Core Guidelines call such a rule an invariant, a condition on the data that the constructor sets up and every public member function keeps true, and make it C.2: “Use class if the class has an invariant; use struct if the data members can vary independently”. C.8 adds “Use class rather than struct if any member is non-public”.
Point’s x and y can each be anything. A thermostat’s target must stay between 5 and 30, so the data is private and set checks it:
class Thermostat {
int target = 20; // the rule: always between 5 and 30
public:
bool set(int t) {
if (t < 5 || t > 30) {
return false; // refused: target keeps its value
}
target = t;
return true;
}
int get() const { return target; }
};— end example]
Called in turn with 22, 45, 3 and 30, set accepted 22, refused 45 and 3 with the target left at 22, then accepted 30. With target public, any line of the program could set it to 45. Both guidelines are conventions: a struct with a private: member compiles, and the keyword tells the next reader whether to expect a rule.
Is a struct faster, smaller or a value type?
Not faster or smaller: the asserts above found the same size and the same type traits for A and B on all four compilers, so the keyword changed neither. And a class is as much a value type as a struct: a variable of either kind holds the object itself, not a reference to one, and the a = b the compiler writes for you copies every member, whichever keyword declared the type. Where an object lives depends on how you create it, not on the keyword.
What is the difference between a C struct and a C++ struct?
A C struct holds data only, and C names its type struct Point (lookup and name spaces in C): Point p; needs a typedef first, while C++ accepts plain Point p; without one.
struct Point {
int x;
int y;
};
int main(void) {
Point p = {3, 4}; // C: error; C++: fine
printf("%d %d\n", p.x, p.y);
return 0;
}— end example]
Built as C, all four rejected the Point p line; Clang said must use 'struct' tag to refer to type 'Point'. Built as C++, all four printed 3 4. A function inside the struct went the same way: rejected as C, compiled as C++. A C struct’s member list holds only variable declarations, bit-fields and static assertions (struct declaration in C), so it has no member functions, no access labels and no base classes.
Can you mix struct and class in declarations and templates?
Yes: a type declared with struct may be defined with class, and the other way round, and the definition decides the defaults. After class Gadget;, the definition struct Gadget { int id = 8; }; left id public on all four compilers. MSVC and Clang warn about the mismatch, so give each type one keyword.
A template parameter is the one place they are not interchangeable: a parameter that stands for a type is written class T or typename T ([temp.param]); struct T there never makes a type parameter, and the sample’s template <struct T> did not compile on any of the four.
Struct or class: which should you write?
| Your type | Write |
|---|---|
| All members public, any value allowed | struct |
| Any private member | class |
| A rule the constructor or a member function enforces | class |
| A small bundle returned from a function | struct |
| A header shared with C code | struct |
More answers about the core language are in Language.
Questions
Can a struct have member functions and constructors in C++?
Yes. A C++ struct can have everything a class has: constructors, a destructor, member functions, virtual functions, private members and base classes. A struct with a constructor, a virtual function and a private member compiled on MSVC, GCC and Clang. Only the default access differs: public in a struct, private in a class.
Can a struct inherit from a class in C++?
Yes, and a class can inherit from a struct. The default inheritance follows the keyword of the type being defined, not of its base: struct Loud : Base inherits publicly and class Quiet : Base privately, whichever keyword declared Base. Write public before the base name and both inherit publicly.
Is a struct stored on the stack and a class on the heap?
No. The keyword decides only the default access. Where an object lives depends on how you create it: a non-static local variable of either kind lives on the stack until the end of its block, and new creates either kind on the heap.
Should a beginner use struct or class?
Use struct for a bundle of public data whose members can each take any value, such as a point or a record, and class for a type with private data or a rule to keep. That is the convention of the C++ Core Guidelines, rules C.2 and C.8. The compiler accepts either; the keyword tells the next reader what to expect.
Sources
- Class declarationcppreference.com
- [class.access.general] Member access controlC++ standard working draft
- [class.access.base] Accessibility of base classes and base class membersC++ standard working draft
- [temp.param] Template parametersC++ standard working draft
- C.2: Use class if the class has an invariant; use struct if the data members can vary independentlyC++ Core Guidelines
- C.8: Use class rather than struct if any member is non-publicC++ Core Guidelines
- Struct declaration (C)cppreference.com
- Lookup and name spaces (C)cppreference.com