Classes: objects and their lifetime
A class is a blueprint for a type of your own: it bundles data with the functions that work on it, and it guards that data. Follow a small class, Tally, as main makes two objects from it: watch the constructor fill each object's memory, a member function change it, private keep outside code away, and the destructor run by itself when each object's scope ends, newest first. That fixed timing is the idea behind RAII.
5 quick questions
Pick an answer to see why. Your score saves with your progress.
01What does Tally t{5}; do?
Writing a class only describes the type. Tally t{5}; makes an object of that type; its constructor, Tally(int s) : n{s} {}, runs with s = 5, and the object's lifetime begins when the constructor finishes.
02In class Tally, n is declared before public:. What happens if main writes t.n = 9;?
Members of a class are private until a public: label. Access is checked by the compiler, so t.n = 9; in main is a compile error. Outside code changes n only through functions the class offers, such as add.
03What does the const in int get() const promise?
A const member function may read the object's members but not change them; writing n = 0; inside get would not compile.
04main makes t, then u inside an inner { } block. In what order do the destructors run?
A local object is destroyed when its scope ends: u at the inner }, which prints bye 1, then t at main's }, which prints bye 8. Local objects are destroyed in reverse order of construction.
05Why is RAII reliable?
The constructor gets the resource and the destructor gives it back. Since C++ calls the destructor whenever the object's scope ends, by the closing brace, a return or a caught exception, the resource is released on every normal way out.
Glossary
- Class
- A type you define: data members plus the member functions that work on them. class Tally { ... }; is one.
- Object
- One thing made from a class, with its own copy of the data members. t and u are two Tally objects.
- Data member
- A variable inside a class; every object has its own. Tally's data member is int n.
- Member function
- A function declared inside a class that works on one object's data, called as object.function(), for example t.add(3).
- Constructor
- A member function with the class's name and no return type. It runs when an object is made and sets it up.
- Destructor
- A member function named ~ plus the class name. It runs by itself when an object's lifetime ends, for a local object at the end of its scope.
- private / public
- Access labels. Private members can be used only by the class's own members; public ones by anyone. A class starts private, a struct public.
- RAII
- Resource Acquisition Is Initialization: the constructor gets a resource and the destructor releases it, so the object's lifetime manages the resource.
Notes and sources
- The two cards are one file, tally.cpp, which starts with #include <iostream>. Build it with g++ -std=c++20 tally.cpp -o tally and run ./tally: it prints 8, bye 1 and bye 8 on three lines.
- The figure draws each object as one box holding its n. Member functions are not stored in the object: their code exists once for the whole class. On common compilers sizeof(Tally) equals sizeof(int), usually 4 bytes; real addresses differ from run to run.
- Precisely, an object's lifetime begins when its initialization (here, the constructor) is complete and ends when its destructor call starts. Objects with automatic storage duration, like t and u, are destroyed at the end of the block they were made in, in reverse order of construction.
- Exact error messages differ between compilers. GCC says 'int Tally::n' is private within this context; Clang says 'n' is a private member of 'Tally'.
- class and struct both define classes. They differ only in default access: members (and base classes) of a class are private until a public: label; those of a struct are public.
- Destructors also run while a caught exception unwinds the stack. They do not run for local objects when the program stops abruptly: std::exit, std::abort, or an exception nobody catches (then whether the stack unwinds is up to the implementation). Copying and moving objects, which decide what happens when an object is duplicated or handed over, build on the constructor and destructor shown here.
- cppreference.com: Classes
- cppreference.com: Access specifiers
- cppreference.com: Constructors and member initializer lists
- cppreference.com: Non-static member functions (const member functions)
- cppreference.com: Destructors
- cppreference.com: Lifetime
- cppreference.com: RAII
- Standard C++ Foundation (isocpp.org): Classes and Objects FAQ
- Standard C++ Foundation (isocpp.org): Destructors FAQ
- C++ Core Guidelines, R.1: Manage resources automatically using RAII
Quiz Unlocks after the last step.