2.1 Class Declaration, Access Specifiers & Member Functions
What is a Class?
A class is a user-defined data type that bundles data (data members) and functions (member functions) together. It is the central construct of OOP.
class ClassName {
access-specifier:
data members;
member functions;
access-specifier:
...
}; // ← semicolon required
Minimal example
class Student {
private:
int id;
string name;
float marks;
public:
void setData(int i, string n, float m) {
id = i;
name = n;
marks = m;
}
void display() {
cout << "ID: " << id
<< ", Name: " << name
<< ", Marks: " << marks << endl;
}
};
int main() {
Student s;
s.setData(101, "Rohit", 88.5);
s.display();
return 0;
}
Terminology
| Term | Meaning |
|---|---|
| Class | Blueprint / type definition |
| Object / Instance | Variable of class type — actual data in memory |
| Data member / Attribute / Field | Variable inside a class |
| Member function / Method | Function inside a class |
| Access specifier | public / private / protected |
| Instance | A specific object (e.g. s above) |
---
Class vs Structure — exam classic
C++ inherits struct from C and adds OOP. The only difference between class and struct in C++ is default access:
| Aspect | struct | class |
|---|---|---|
| Default access | public | private |
| Default inheritance | public | private |
| Use case (idiom) | Plain data (POD) | OOP entities with behaviour |
| OOP features | All supported | All supported |
| Inheritance | Allowed | Allowed |
| Member functions | Allowed | Allowed |
| Constructors / Destructors | Allowed | Allowed |
| Access specifiers | All work | All work |
struct Point {
int x, y; // public by default
};
class Point {
int x, y; // private by default — invisible outside
};
Idiom: Usestructfor plain data with no invariants; useclassfor objects with behaviour or invariants to protect.
---
Access Specifiers
public, private, protected control who can access the members.
| Specifier | Access from class itself | Access from derived class | Access from outside |
|---|---|---|---|
public | ✓ | ✓ | ✓ |
protected | ✓ | ✓ | ✗ |
private | ✓ | ✗ | ✗ |
Default access
class→privatestruct→public
Example with all three
class Account {
private:
double balance; // hidden — only Account methods access it
protected:
string accountType; // visible to Account and its derived classes
public:
string holderName; // visible everywhere
void deposit(double amt) {
balance += amt; // OK — internal access
}
double getBalance() {
return balance;
}
};
class SavingsAccount : public Account {
public:
void demo() {
accountType = "Savings"; // OK — protected accessible to derived
// balance = 0; // ERROR — private not visible
holderName = "Rohit"; // OK — public accessible
}
};
int main() {
Account a;
a.holderName = "Rohit"; // OK — public
a.deposit(1000); // OK — public
// a.balance = 5000; // ERROR — private
// a.accountType = "X"; // ERROR — protected from outside
return 0;
}
---
Member Functions
Member functions are functions defined inside a class. Two ways to define:
1. Inside the class (implicitly inline)
class Circle {
private:
double radius;
public:
void setRadius(double r) { radius = r; }
double area() { return 3.14 * radius * radius; }
};
2. Outside the class (using :: scope resolution)
class Circle {
private:
double radius;
public:
void setRadius(double r);
double area();
};
void Circle::setRadius(double r) {
radius = r;
}
double Circle::area() {
return 3.14 * radius * radius;
}
The outside form is preferred for any function longer than 1-2 lines — keeps the class declaration clean.
Member function categories
| Category | Purpose | Example |
|---|---|---|
| Constructor | Initialise object | Student(int i, string n) |
| Destructor | Clean up object | ~Student() |
| Accessor / Getter | Read private data | int getId() const |
| Mutator / Setter | Modify private data | void setId(int i) |
| Utility / Helper | Internal helper | private functions |
| Static | Belongs to class, not instance | static int count() |
| Const | Promises not to modify object | int getId() const |
| Virtual | For polymorphism (Unit III) | virtual void draw() |
| Friend | Not a member, but has access | friend void print(A&) |
| Operator | Overload operator (Unit III) | A operator+(const A&) |
---
const Member Functions
A const member function promises not to modify the object's state. It can be called on const objects.
class Student {
private:
int id;
string name;
public:
int getId() const { // const — doesn't modify
// id = 5; // ERROR — would modify
return id;
}
void setId(int i) { // non-const
id = i;
}
};
const Student s; // const object
s.getId(); // OK — const function
// s.setId(5); // ERROR — non-const function on const object
Rule of thumb: Make every member functionconstby default; removeconstonly when the function genuinely modifies state.
---
Arrays Within a Class
A class can have arrays as data members:
class Marks {
private:
int subjects[5];
public:
void setMarks() {
for (int i = 0; i < 5; i++) cin >> subjects[i];
}
float average() {
int sum = 0;
for (int i = 0; i < 5; i++) sum += subjects[i];
return sum / 5.0;
}
};
---
Array of Objects
You can create an array where each element is an object:
class Student {
public:
int id;
string name;
void display() { cout << id << " " << name << endl; }
};
int main() {
Student class10[5]; // array of 5 Student objects
class10[0].id = 101;
class10[0].name = "Rohit";
class10[1].id = 102;
class10[1].name = "Priya";
for (int i = 0; i < 5; i++) class10[i].display();
return 0;
}
Dynamic array of objects
Student* students = new Student[5];
// ... use
delete[] students;
Modern C++ — vector
vector<Student> students;
students.push_back({101, "Rohit"});
students.push_back({102, "Priya"});
for (auto& s : students) s.display();
---
Memory Allocation of Objects
What memory does an object occupy?
class Point {
int x; // 4 bytes
int y; // 4 bytes
};
sizeof(Point); // 8 bytes
For a class with non-virtual functions, sizeof is the sum of data member sizes plus padding for alignment. Member functions are stored once for the class, not per object.
With virtual functions (Unit III)
class A {
int x;
virtual void f();
};
sizeof(A); // 16 on 64-bit — x (4) + padding (4) + vtable pointer (8)
Virtual functions add a vtable pointer (vptr) to each object.
Where are objects stored?
| Where declared | Memory |
|---|---|
| Local in function | Stack |
| Global / static | Data segment |
new allocated | Heap |
| Inside another object | Same region as containing object |
---
Passing Objects as Arguments
Pass by value (copy)
void process(Student s) {
s.id = 999; // doesn't affect caller's object
}
Expensive for large objects — copy is made.
Pass by reference
void process(Student& s) {
s.id = 999; // modifies caller's object
}
No copy. Modifications visible to caller.
Pass by const reference (idiom)
void process(const Student& s) {
// s.id = 999; // ERROR — can't modify
cout << s.id;
}
No copy AND no modification. This is the default idiom for reading parameters in modern C++.
Pass by pointer
void process(Student* s) {
if (s != nullptr) s->id = 999;
}
---
Returning Objects from Functions
Student createStudent(int id, string name) {
Student s;
s.id = id;
s.name = name;
return s;
}
Modern compilers use RVO (Return Value Optimisation) and move semantics to eliminate the copy.
Return by reference (use with care)
Student& getStudent(int i) {
static Student store[100]; // must outlive function
return store[i];
}
⚠ Never return a reference to a local variable — it's destroyed when the function exits.
---
Class Design Best Practices
- Make data members
private. Provide getters/setters only when necessary. - Single responsibility — each class does one thing.
- Keep classes small. > 7-10 members suggests it should be split.
consteverything that can be const.- Pass large objects by const reference, not value.
- Provide clear public interface — make the contract obvious.
- Document invariants — what must be true at all times.
---
Key Terms — Lesson 2.1
The terms below define class fundamentals — every PYQ on classes, access, or object basics expects fluent use.
Class — A user-defined type that bundles data members (attributes) and member functions (methods) into a single unit, with access specifiers controlling visibility. A class is a blueprint; declaring a class allocates no memory.
Object — A runtime instance of a class — a concrete entity with its own copy of the data members. Declaring Student s; creates an object s of class Student, allocating memory for its data members.
Data Member — A variable declared inside a class that contributes to each object's state. Each object has its own copy. Also called an attribute, field, or instance variable.
Member Function / Method — A function declared inside a class that operates on the class's data. Invoked using the dot operator on an object: s.display(). Has implicit access to the object's data via the this pointer.
Access Specifier — A keyword that controls visibility of class members. public members are accessible from any code that can see the object. private members are accessible only within the class itself (and its friends). protected members are accessible within the class and its derived classes (used in inheritance).
private (default) — The default access for class members in C++. Private members can only be accessed by methods of the same class (or its friends). The basis of data hiding.
public — The access specifier that makes members visible to any code that can see the object. The public members of a class form its interface — the contract it offers to the rest of the program.
protected — The access specifier that makes members visible within the class and its derived classes, but not to unrelated code. Used when a class wants to share implementation details with subclasses without making them globally visible.
Class vs Struct — In C++, the only language difference is the default access: class defaults to private, struct defaults to public. By convention, struct is used for "plain data" with no invariants, and class is used when there is encapsulated behaviour. Both can have member functions, constructors, virtual methods, and inheritance.
Interface — The public members of a class — the methods and data exposed to users of the class. The interface is the contract: it should be stable, clearly named, and minimal.
Implementation — The private members and the bodies of public methods — the internal mechanism by which the interface is delivered. Implementation can change freely as long as the interface contract is preserved.
Encapsulation (recap) — Bundling data and the operations on that data inside a single class, with private data accessed only through public methods. Encapsulation is the practical mechanism that delivers data hiding and information hiding.
Member Initialiser List — A C++ syntax for initialising data members before the constructor body runs: Student(int i, string n) : id(i), name(n) {}. Required for const members, references, and members with no default constructor. More efficient than assigning inside the body.
Inline Member Function — A member function whose body is defined inside the class definition. Such functions are implicitly inline — the compiler may substitute their body at call sites. Defining methods outside the class body (using the scope operator Class::method()) is non-inline by default.
Scope Resolution for Methods — When a method is defined outside the class, the class is named with the scope operator: void Student::display() { ... }. This tells the compiler which class the method belongs to.
this Pointer — An implicit pointer available inside every non-static member function, pointing to the object on which the method was called. Allows the method to refer to the current object's members and disambiguate them from parameters with the same name. Covered in detail in Lesson 2.2.
Array of Objects — Declaring an array whose elements are instances of a class: Student class[40];. Each element is a fully-formed object with its own data members. Initialisation calls the default constructor for each element.
Object Composition — Building a class by including objects of other classes as data members. A Library class might contain a vector<Book> and a vector<Member>. Composition models the "has-a" relationship and is the modern preferred alternative to inheritance for code reuse.
Member Object — A data member that is itself an object of another class. The class containing it is the containing class; member objects are constructed before the containing object's constructor body runs and destroyed after the containing object's destructor body runs.
Forward Declaration — A declaration like class Student; that announces a class exists without defining it. Useful when one class only needs to declare a pointer or reference to another (avoiding header inclusion and reducing compile time).
Header File / Implementation File — The common C++ split: the .h header file contains class declarations (the interface), and the .cpp implementation file contains method definitions. Code using the class includes the header; the implementation is compiled separately and linked.
const Member Function — A member function declared with const after the parameter list: int getMarks() const;. Guarantees that the function will not modify the object's state. Can be called on const objects; cannot call non-const members from within.
Getter / Setter (Accessor / Mutator) — Conventional methods for reading and writing private data members through the public interface. getMarks() returns the value; setMarks(int m) updates it, often with validation. Getters are typically const; setters typically validate.
Invariant — A condition that must always be true about an object's state — e.g., "BankAccount balance is never negative." Constructors establish invariants; methods preserve them. Invariants are the heart of encapsulated design.
Memory Allocation of Objects — When a class object is declared, memory is allocated for all its data members in declaration order, with possible padding for alignment. Methods are not stored per-object — they exist once in the program's code section, shared by all objects of the class.
Padding / Alignment — The compiler inserts unused bytes between data members to satisfy hardware alignment requirements (e.g., 4-byte ints must start at addresses divisible by 4). sizeof(object) may be larger than the sum of the member sizes because of padding.
Static Data Member — A data member declared with static that is shared by all objects of the class — there is only one copy, regardless of how many objects exist. Covered in detail in Lesson 2.2.
---
Study deep
- The "interface vs implementation" split is sacred. Public members = interface. Private members = implementation. Changing implementation should not break callers. This is the practical meaning of encapsulation.
- Class layout is implementation-defined. The C++ standard guarantees member order, but exact padding is up to the compiler. Don't rely on
sizeofbeing the sum of member sizes — alignment may add padding.
structvsclassis convention, not capability. Both can have private members, virtual functions, inheritance. Usestructto signal "this is plain data"; useclassto signal "this has encapsulated behaviour".
constcorrectness is hard but valuable. Once you propagateconstthrough a codebase, the compiler catches a whole class of bugs. Start with parameters; expand to member functions.
- Modern C++ encourages "value semantics". Return objects, pass by const reference, use move semantics. Avoid raw pointers in interfaces unless ownership is unclear.
PYQ pattern (very common): "What is a class? Differentiate class and structure in C++." — Define class as user-defined type bundling data + functions; show example; table the differences (default access, default inheritance, idiom).
PYQ pattern: "Explain access specifiers in C++ with example." — Define public/private/protected; table the 3-row visibility matrix; show example with all three.
PYQ pattern: "Write a C++ program to create a class Student with private members ID and Name and public functions to set/display. Demonstrate using array of objects." — Class with private + public sections; setData/display; array of 5 Student objects; loop input/output.