OOP · ENCT 151

Ch 3. Objects and Classes

7 hours · 9 marks (largest chapter)

3.1 C++ Classes

A class is a user-defined blueprint that groups data members (attributes) and member functions (methods) into one unit. Declared with the keyword class.

class Student {
private:
    int roll;
    string name;
public:
    void setData(int r, string n) { roll = r; name = n; }
    void display() { cout << roll << " " << name; }
};

Access specifiers control visibility: private (accessible only inside the class — default for class), protected (accessible in class and derived classes), public (accessible anywhere the object is visible).

3.2 Objects and Member Access

An object is an instance of a class — creating an object allocates memory for its data members.

Student s1;                 // object creation
s1.setData(1, "Ram");       // member access using dot (.) operator
s1.display();
Student *sp = &s1;
sp->display();               // member access via pointer using ->

3.3 Relation of Object, Class and Memory

3.4 Defining Member Function (inside the class)

class Box {
    int length;
public:
    void setLength(int l) { length = l; }   // defined inside class -> implicitly inline
};

3.5 Defining Member Function Outside the Class (using scope resolution)

class Box {
    int length;
public:
    void setLength(int l);       // declaration only
    int getLength();
};
void Box::setLength(int l) { length = l; }  // :: scope resolution operator
int Box::getLength() { return length; }

Functions defined outside the class using :: are NOT implicitly inline (unless explicitly marked inline), whereas functions defined inside the class body are implicitly treated as inline requests.

3.6 Objects as Members (Composition)

A class can contain objects of another class as its data members — this is called composition or a has-a relationship.

class Engine { public: void start() { cout << "Engine started"; } };
class Car {
    Engine e;    // Engine object as a member of Car
public:
    void drive() { e.start(); cout << " Car moving"; }
};

3.7 Constructors and Destructors

Constructor: a special member function with the same name as the class, automatically invoked when an object is created; used to initialize data members. No return type (not even void).

Destructor: a special member function named ~ClassName(), automatically invoked when an object is destroyed; used to release resources. Takes no arguments, cannot be overloaded, and has no return type.

TypeDescription
Default constructorTakes no arguments; compiler supplies one if none is defined.
Parameterized constructorTakes arguments to initialize members with specific values.
Copy constructorClassName(const ClassName &obj) — creates a new object as a copy of an existing object.
class Demo {
    int x;
public:
    Demo() { x = 0; cout << "Default ctor\n"; }              // default
    Demo(int a) { x = a; cout << "Param ctor\n"; }            // parameterized
    Demo(const Demo &d) { x = d.x; cout << "Copy ctor\n"; }   // copy
    ~Demo() { cout << "Destructor\n"; }
};
int main() {
    Demo d1;        // default ctor
    Demo d2(5);      // param ctor
    Demo d3 = d2;    // copy ctor
}                     // destructors called in reverse order: d3, d2, d1

3.8 Objects as Function Arguments

Objects can be passed to functions by value (a copy is made using the copy constructor), by reference (&, no copy, changes affect original), or by pointer.

void show(Demo d) { }          // pass by value -> copy constructor invoked
void show(Demo &d) { }         // pass by reference -> no copy
void show(Demo *d) { }         // pass by pointer

3.9 Returning Objects from Functions

class Point {
    int x, y;
public:
    Point(int a=0, int b=0): x(a), y(b) {}
    Point add(Point p) {              // returns a new Point object by value
        return Point(x + p.x, y + p.y);
    }
};

When a function returns an object by value, a temporary object is created (often optimized away by the compiler via return value optimization, RVO).

3.10 Array of Objects

class Student { public: int roll; };
Student s[3];       // array of 3 Student objects, default ctor called 3 times
s[0].roll = 1;
s[1].roll = 2;

3.11 Pointer to Objects

Student *p = new Student;   // dynamically allocated object
p->roll = 5;                  // access member via ->
delete p;
Student arr[3];
Student *q = arr;             // pointer to first element
(q+1)->roll = 10;             // access second element via pointer arithmetic

3.12 Dynamic Memory Allocation for Objects

Student *p = new Student();          // single object on heap
Student *arr = new Student[5];       // array of objects on heap
delete p;
delete[] arr;                         // must use [] for arrays

3.13 Dynamic Constructors

A constructor that allocates memory dynamically (using new) for a data member at object-creation time — commonly used when the size of a member (e.g., a string or array) is not known until run time.

class Str {
    char *data;
public:
    Str(const char *s) {
        data = new char[strlen(s) + 1];   // dynamic allocation inside constructor
        strcpy(data, s);
    }
    ~Str() { delete[] data; }              // must free in destructor
};

Classes with dynamic constructors must also define a proper copy constructor and destructor (the "Rule of Three") to avoid shallow-copy bugs (two objects pointing to and freeing the same memory).

3.14 Pointer (this pointer)

Every non-static member function has an implicit parameter called this — a pointer to the object that invoked the function. Used to resolve naming conflicts between a parameter and a data member, and to return the current object (e.g., for chaining).

class Box {
    int length;
public:
    Box &setLength(int length) {
        this->length = length;   // 'this->length' is the member, 'length' is the parameter
        return *this;             // enables chaining: obj.setLength(1).setLength(2);
    }
};

3.15 Static Data Member and Static Member Function

Static data member: shared by all objects of the class — only one copy exists regardless of how many objects are created. Must be defined (given storage) outside the class.

Static member function: can be called without an object (using the class name), and can only access other static members directly (it has no this pointer).

class Counter {
    static int count;              // declaration
public:
    Counter() { count++; }
    static int getCount() { return count; }  // static function
};
int Counter::count = 0;             // definition + initialization (outside class)
int main() {
    Counter a, b, c;
    cout << Counter::getCount();   // 3 -- called using class name
}

3.16 Constant Member Functions and Constant Objects

class Box {
    int length;
public:
    int getLength() const { return length; }  // const member function: cannot modify data members
};
const Box b;             // constant object: can only call const member functions on it
// b.getLength();          -> OK
// b.setLength(5);         -> error if setLength is non-const

A const member function guarantees it will not modify the object's data members (except members marked mutable). A const object can only invoke const member functions.

3.17 Friend Functions and Friend Classes

A friend function is a non-member function granted access to a class's private and protected members. A friend class grants all member functions of another class the same access.

class Box {
    int length;
public:
    Box(int l): length(l) {}
    friend void printLength(Box b);   // friend declaration inside class
};
void printLength(Box b) {              // NOT a member function, but can access b.length
    cout << b.length;
}

class B; // forward declaration
class A {
    friend class B;   // B can access A's private members
    int secret = 42;
};
class B {
public:
    void reveal(A a) { cout << a.secret; }
};

Friendship is not mutual and not inherited: if A declares B as a friend, B does not automatically consider A a friend, and derived classes of B do not automatically gain the friendship either.

Most Probable Questions

Q1. Define class and object. Write a C++ program to define a class Rectangle with member functions to set dimensions and calculate area. 6 marks
A class is a user-defined blueprint describing data and behaviour; an object is an instance of a class occupying its own memory.
class Rectangle {
    float length, width;
public:
    void setDimension(float l, float w) { length = l; width = w; }
    float area() { return length * width; }
};
int main() {
    Rectangle r;
    r.setDimension(4, 5);
    cout << r.area();   // 20
}
Q2. What are constructors and destructors? Explain their types with a program showing constructor overloading. 7 marks
See section 3.7 for definitions and the table of constructor types. Include the example program that shows default, parameterized, and copy constructors plus the destructor, and explain that objects are destroyed in the reverse order of their creation (LIFO).
Q3. What is the this pointer? Explain its uses with an example. 4 marks
this is an implicit pointer available inside every non-static member function, pointing to the calling object. Uses: (1) disambiguate a data member from a parameter of the same name, (2) return the current object by reference to support method chaining, (3) pass the current object to another function. See code in section 3.14.
Q4. Differentiate between static data member and ordinary (instance) data member. 4 marks
An ordinary data member has a separate copy in every object. A static data member has exactly one copy shared by all objects of the class, exists even if no object is created (once defined), must be defined outside the class to allocate storage, and is typically used for values common to the whole class (e.g., an object counter).
Q5. What is a friend function? Write a program to add two distances of different classes using a friend function. 6 marks
A friend function is a non-member function that is granted access to a class's private/protected data, declared inside the class with the friend keyword.
class ClassB;
class ClassA {
    int a = 10;
public:
    friend int addValues(ClassA, ClassB);
};
class ClassB {
    int b = 20;
public:
    friend int addValues(ClassA, ClassB);
};
int addValues(ClassA x, ClassB y) { return x.a + y.b; }
int main() { cout << addValues(ClassA(), ClassB()); } // 30
Q6. Explain dynamic constructors with a suitable example. 5 marks
A dynamic constructor allocates memory for a data member at run time using new, useful when the required size is unknown at compile time (e.g., a variable-length string). See the Str class example in section 3.13; explain why the destructor must free this memory and why a proper copy constructor is also required to prevent two objects sharing (and both freeing) the same memory block.
Q7. What is the difference between passing an object by value and by reference to a function? 4 marks
Pass by value invokes the copy constructor to create a new copy of the object for the function — changes inside the function do not affect the caller's object, and copying can be expensive for large objects. Pass by reference passes an alias to the original object — no copy is made, it is more efficient, and changes made inside the function affect the caller's object directly.
Q8. What are constant member functions? Why are they needed? 4 marks
A member function declared with const after its parameter list guarantees that it will not modify any data member of the object (except mutable members). They are needed so that const objects (and references/pointers to const objects) can still call safe, read-only methods — without const member functions, a const object could call no member functions at all. See section 3.16.
Q9. Write a program to demonstrate an array of objects. 5 marks
class Student {
    int roll; string name;
public:
    void set(int r, string n) { roll = r; name = n; }
    void show() { cout << roll << " " << name << endl; }
};
int main() {
    Student s[3];
    s[0].set(1, "Ram"); s[1].set(2, "Shyam"); s[2].set(3, "Hari");
    for (int i = 0; i < 3; i++) s[i].show();
}
Q10. Explain the relation between object, class and memory allocation. 4 marks
See section 3.3: a class itself is only a template and occupies no memory for data members; each object gets its own copy of the class's non-static data members, while all objects share the same member function code (invoked with a different this pointer per object).
Q11. What is a friend class? How is it different from inheritance? 4 marks
A friend class is granted access to another class's private/protected members without being related to it by inheritance. Unlike inheritance, a friend class does NOT acquire the other class's members, does not establish an is-a relationship, and friendship is neither mutual nor inherited by subclasses (see section 3.17).
← Chapter 2 Next: Chapter 4 — Operator Overloading →