DEV Community

Yilong Wu
Yilong Wu

Posted on

C++ struct vs class — The Only Difference That Matters (Plus Real Use Cases)

Hi everyone! I'm AlanWu, a junior high school C++ learner. When I first saw both struct and class in C++, I was confused. I thought struct was just a C thing — a bag of variables with no functions. But in C++, you can put methods, constructors, inheritance — everything — in a struct.

So what's the actual difference? Here's the one-sentence answer, plus practical guidance on when to use which.

My GitHub: https://github.com/Cn-Alanwu


The One-Sentence Difference

In C++, struct and class are identical in every way — except the default access level: struct members are public by default; class members are private by default.

That's it. Everything else — inheritance, constructors, destructors, member functions, templates, virtual functions — works exactly the same in both.

struct S {
    int x;  // public by default
};

class C {
    int x;  // private by default
};

int main() {
    S s;
    s.x = 5;   // OK — public

    C c;
    // c.x = 5;  // ERROR — private
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

If you add public: to the class, the two become completely identical:

class C {
public:
    int x;  // now public — exactly like struct
};
Enter fullscreen mode Exit fullscreen mode

The Inheritance Difference (Same Rule)

The same access rule applies to inheritance:

struct Base {};
struct Derived : Base {};  // public inheritance by default

class Base2 {};
class Derived2 : Base2 {};  // private inheritance by default
Enter fullscreen mode Exit fullscreen mode

This means if you use class and forget to write public before the base class name, you get private inheritance — which is almost never what you want. It's a common beginner trap.

class Animal {
public:
    void eat() {}
};

// WRONG — private inheritance by default
class Dog : Animal {
};

int main() {
    Dog d;
    // d.eat();  // ERROR — eat() is private in Dog
    return 0;
}

// FIXED
class Dog : public Animal {
};
Enter fullscreen mode Exit fullscreen mode

So When Do I Use Which?

After a year of C++, here's my personal rule — and it's not about the technical difference at all. It's about what you're communicating to other programmers.

Use struct when:

  • It's a simple data container — just a bundle of related values
  • All members can safely be public
  • There's no invariant to protect (no rule like "age must be positive")
  • Examples: a point (x, y), a configuration settings bundle, a return value from a function
struct Point {
    double x, y;
};

struct Config {
    int width;
    int height;
    bool fullscreen;
};

// struct is great for returning multiple values
struct SearchResult {
    bool found;
    int index;
    std::string message;
};

SearchResult find(const std::vector<int>& v, int target) {
    for (size_t i = 0; i < v.size(); i++) {
        if (v[i] == target) return {true, (int)i, "Found"};
    }
    return {false, -1, "Not found"};
}
Enter fullscreen mode Exit fullscreen mode

Use class when:

  • You want encapsulation — hiding internal data behind methods
  • There's an invariant to protect (like "balance never goes below zero")
  • You expect the internal representation to change later
  • You're building something with behavior, not just data
class BankAccount {
private:
    double balance = 0.0;

public:
    void deposit(double amount) {
        if (amount > 0) balance += amount;
    }

    bool withdraw(double amount) {
        if (amount > 0 && balance >= amount) {
            balance -= amount;
            return true;
        }
        return false;
    }

    double getBalance() const {
        return balance;
    }
};
Enter fullscreen mode Exit fullscreen mode

Real Example from My Project: algorithmCombination

In my header-only algorithm library, I use struct and class side by side:

// struct — pure data, no invariants
template<typename T>
struct Pair {
    T first, second;
};

// class — has behavior, needs encapsulation
template<typename T>
class Stack {
private:
    std::vector<T> data;

public:
    void push(const T& val) {
        data.push_back(val);
    }

    T pop() {
        if (data.empty()) throw std::runtime_error("Stack is empty");
        T val = data.back();
        data.pop_back();
        return val;
    }

    bool empty() const { return data.empty(); }
    size_t size() const { return data.size(); }
};
Enter fullscreen mode Exit fullscreen mode

The Pair is just two values glued together — struct. The Stack has rules (can't pop when empty) — class.


What About C Compatibility?

If you're writing a header that might be included in C code, use struct — C doesn't have class. But if you're writing pure C++ (which most of us are), C compatibility is rarely a concern.

// C-compatible
struct Point {
    double x, y;
};
// Works in both C and C++

// C++ only
class Point {
public:
    double x, y;
    double distance() const { return sqrt(x*x + y*y); }
};
// C can't use this — it has a member function
Enter fullscreen mode Exit fullscreen mode

Summary Table

Feature struct class
Default member access public private
Default inheritance public private
Can have methods? Yes Yes
Can have constructors? Yes Yes
Can use virtual functions? Yes Yes
Can use templates? Yes Yes
Conventional use Plain data bundles Encapsulated objects

The Real Takeaway

Don't overthink this. If you're coming from C, struct feels natural for data. If you're coming from Java, class feels natural for everything. Both are correct — just be consistent.

In my projects, I follow this rule: if all members are public and there are no invariants, I use struct. If anything is private or needs protection logic, I use class. That's it.

The compiler doesn't care. But whoever reads your code six months later (including you) will appreciate the signal.

GitHub: https://github.com/Cn-Alanwu

Top comments (0)