OOP & concepts

C vs C++: the main differences, from an object-oriented point of view

OOP & concepts · · Published 2026-08-20

C is a procedural language: programs are functions operating on data structures. C++ began as "C with classes" and keeps almost all of C, adding the tools of object-oriented and generic programming. The differences matter in interviews and when reading older code that mixes the two.

At a glance

FeatureCC++
ParadigmProceduralMulti-paradigm: procedural, object-oriented, generic, functional elements
Classes, access controlNo (struct holds data only)class/struct with member functions, public/private/protected
Inheritance, virtual functionsNoYes, including multiple inheritance
Function overloadingNoYes
Generic codeMacros, void*Templates
Memory managementmalloc/freenew/delete, constructors/destructors, smart pointers
Error handlingReturn codes, errnoExceptions (plus return codes)
ReferencesPointers onlyPointers and references
NamespacesNoYes
Standard libraryC standard libraryC library plus containers, algorithms, strings, streams…

The same idea in both

/* C: data and functions are separate */
typedef struct { double balance; } Account;

void deposit(Account *a, double amount) { if (amount > 0) a->balance += amount; }
// C++: the class bundles data and behaviour and hides the state
class Account {
public:
    explicit Account(double opening) : balance_(opening) {}
    void deposit(double amount) { if (amount > 0) balance_ += amount; }
    double balance() const { return balance_; }
private:
    double balance_;
};

In the C version any code can write a->balance = -1; in C++ the compiler forbids access to balance_ outside the class. That is encapsulation, the first of the OOP principles explained in OOP concepts with examples.

RAII: the most important C++ idea C lacks

In C++, an object's destructor runs automatically when it goes out of scope. Wrapping a resource in an object (a file, a lock, memory) ties its release to scope: "resource acquisition is initialisation". std::unique_ptr, std::vector and std::lock_guard all work this way, which removes most manual free calls and leaks. C# achieves a similar effect with using and IDisposable, while memory itself is handled by the garbage collector.

Compatibility

Most C code compiles as C++, but not all: C++ is stricter about conversions (for example from void*), reserves more keywords (class, new), and the two standards have diverged on some features since C99. Mixed projects declare C functions with extern "C" so the C++ compiler does not mangle their names.

And C#?

C# borrows its syntax from the C family but runs on a managed runtime: garbage collection, no manual memory management in normal code, single class inheritance with interfaces, generics checked at run time, and a large framework library. See Java vs .NET for how it compares with its closest rival.

References