Menu

C++ Classes: Define Objects, Members, and Methods

Learn how C++ classes bundle data and behavior into reusable types - declaring member variables and methods, creating objects, the public/private split, and the gotchas like uninitialized members and the this pointer.

This page includes runnable editors - edit, run, and see output instantly.

What a Class Is

A class is a blueprint for a custom type that bundles data (member variables) and behavior (member functions) into one unit. Where the built-in types like int and double describe single values, a class lets you model a whole concept - a bank account, a 2D point, a player - as a single value you can pass around.

You have already used classes without defining any: std::string and the vector container are classes from the standard library. Calling name.length() or v.push_back(3) is calling a member function on an object. Now you will build your own types the same way, then move on to constructors for initializing them.

Defining a Class and Creating Objects

A class definition lists its members between braces and ends with a semicolon - forgetting that trailing ; is one of the most common beginner errors. Each object you create from the class gets its own copy of the member variables.

rex and luna are two separate objects. Changing rex.name does not touch luna.name - each object holds its own data. You reach a member with the dot operator . on an object (or -> when you have a pointer to one).

public vs private

By default, everything in a class is private: only the class's own member functions can touch it. The public: label opens members up to outside code. This split is the heart of encapsulation - you expose a safe interface and hide the internal data so it can't be put into an invalid state.

Because count is private, no caller can sneak in a negative or nonsensical value - they must go through increment(). The const after value()'s parameter list promises the function won't modify the object, which lets you call it on const objects and signals intent to readers.

Declaration vs. Definition of Methods

For small classes, defining methods inline (as above) is fine. For larger ones, it's common to declare methods inside the class and define their bodies outside, using the ClassName::method scope syntax. This keeps the class definition readable as a summary of the interface.

The Rectangle:: prefix tells the compiler which class the function belongs to. Inside such a definition you still refer to members by their bare names (width, area()) - the compiler knows they belong to the object the method was called on.

The this Pointer

Inside any non-static member function, this is a pointer to the object the function was invoked on. You usually don't need it, since a bare member name already refers to the current object. It earns its keep when a parameter shadows a member - they share a name - and you must disambiguate.

Without this->, writing x = x; inside setX would assign the parameter to itself and leave the member untouched - a silent bug. this->x makes it unambiguous. Many codebases avoid the problem entirely by naming parameters differently (e.g. setX(int newX)), but you will see this-> constantly in real code.

Common Mistakes

A handful of class traps catch people repeatedly:

  • Missing the closing semicolon. A class definition ends with };. Drop the ; and you get a flood of confusing errors pointing at whatever comes after the class, not at the class itself.
  • Forgetting to initialize members. Built-in members like int and double are not zeroed automatically. Reading an uninitialized member is undefined behavior. Give members default values (int count = 0;) or initialize them in a constructor.
  • Accessing private members from outside. c.count = 5; on a private member is a compile error - go through a public method instead. This is the encapsulation working as intended.
  • Confusing the class with an object. Dog.bark(); is wrong - Dog is the type. You call methods on objects: rex.bark();.
// Uninitialized member - reading 'age' is undefined behavior:
class Cat {
public:
    int age;            // no default value
};

Cat c;
std::cout << c.age;     // garbage value, not 0

Next: Constructors

Setting each member by hand after creating an object - rex.name = ...; rex.age = ...; - is tedious and easy to forget, which is exactly how you end up with uninitialized members. The next page covers constructors: special functions that run automatically when an object is created, letting you guarantee every object starts in a valid state with a clean one-line Dog rex("Rex", 4); syntax.

Frequently Asked Questions

What is the difference between a class and an object in C++?

A class is the blueprint - it describes what data (member variables) and behavior (member functions) a type has. An object is a concrete instance built from that blueprint. class Dog { ... }; defines the type once; Dog rex; creates an actual Dog you can use. One class can produce many independent objects.

What is the difference between class and struct in C++?

Technically only the default access level: members of a class are private by default, while members of a struct are public by default. Both can have member functions, constructors, and inheritance. By convention, struct is used for plain data bundles and class for types with behavior and invariants to protect.

What does the this pointer do in a C++ class?

Inside a member function, this is a pointer to the object the function was called on. Use it to disambiguate a parameter from a member (this->x = x;) or to return the current object. You rarely need it for normal member access - writing x already refers to the current object's x.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED