Section 17: Friend and Static Members / Inner Classes
Friend Functions
- Definition: A Friend function is a global function (outside function) which can access all the members of a class upon an object, not directly. It can access private, protected, and public members.
- Declaration: The class must explicitly declare that the function is a "friend," essentially saying: "Though this function doesn't belong to us, it is a friend, so it can access all members of our objects."
- Usage: This is useful mostly in operator overloading.
class Test {
private:
int a;
protected:
int b;
public:
int c;
friend void func(); // Declaration
};
void func() {
Test t;
t.a = 10; // Accessing private
t.b = 10; // Accessing protected
t.c = 10; // Accessing public
}
Friend Class
- If we want one class to access private members of another class upon an object (without inheritance), we have to declare the accessing class as a friend inside the target class.
- Note: You need to declare the friend class (e.g.,
class Your) before the target class (e.g.,class My), otherwise the compiler will not recognize it (Forward Declaration). - They can access members of objects of other classes.
- Container Concept: We can call the friend class a "container" of objects of the other class. If the container class needs to access private or protected members of the contained objects, we declare them as friends.
class Your; // Forward declaration
class My {
private:
int a = 10;
friend Your; // Friend declaration
};
class Your {
public:
My m;
void fun() {
// Accessing private member 'a' of class My
// strictly upon the object 'm'
std::cout << m.a;
}
};
Static Members
- If we create an object of a class, every object will have its own data members declared in the class. However, if we make a data member static, it will remain the same across all objects.
- The static variable/member belongs to the class, not to every object.
- Memory Allocation: The static member memory is allocated only one time and shared among all objects.
- Since static variables belong to the class (not a specific object), all objects share that one copy. If one object changes it, the change is reflected for all.
- Declaration Rule: When we have a static variable inside the class, we must define/initialize it outside again using the scope resolution operator.
-
int ClassName::count = 0; -
It functions like a global variable but is scoped to the class. It can be accessed using objects or the class name.
Visualizing Static Memory:
graph TD
subgraph Heap/Stack Memory
obj1[Object T1]
obj2[Object T2]
obj1 -->|Has its own| a1[int a]
obj2 -->|Has its own| a2[int a]
end
subgraph Static Global Memory
static[Static int count]
end
obj1 -.->|Shares| static
obj2 -.->|Shares| static
style static fill:#f9f,stroke:#333,stroke-width:2px
class Test {
public:
int a;
static int count; // Declaration inside class
Test() {
a = 10;
count++; // Increment shared count
}
};
// Definition outside class is mandatory
int Test::count = 0;
int main() {
Test t1;
Test t2;
// Both t1.count and t2.count refer to the same memory
std::cout << t1.count << std::endl;
std::cout << Test::count << std::endl; // Can access via Class Name
}
Static Member Functions
- Restriction: Static member functions can access only static data members of a class. They cannot access non-static data members.
- Static member functions also belong to the class, not a specific object.
class Test {
public:
int a;
static int count;
// Static Function
static int getCount() {
// a++; // Error: Cannot access non-static member 'a'
return count; // OK: Accessing static member
}
};
int Test::count = 0;
int main() {
// Calling without an object
std::cout << Test::getCount();
// Calling with an object (valid, but typically accessed via class)
Test t;
std::cout << t.getCount();
}
Logic behind Static Members and Functions
- Analogy: If we go to a car showroom, we can know the price of a car (e.g., Innova) without buying the car.
- We have a class named
Innova. We have a static member/function forprice. We don’t need to create an object (buy the car) to access the price; we can access it using the class directly.
Usage Points regarding Static Members
- Counters: Static members can be used as counters (e.g., to count how many objects are active).
- Shared Memory: Used as shared memory for all objects; one object writes, and others read the same data.
- Class Information: Provide information about the class itself (e.g., car price is info about the model, not a specific car instance).
Inner / Nested Classes
- Definition: Writing a class inside another class. This is useful when the inner class is relevant only within the context of the outer class.
- Access Rules:
- The Inner class can access members of the Outer class if they are static.
- The Outer class can create an object of the Inner class.
-
Using that object, the Outer class can access public members of the Inner class. (It typically cannot access private/protected members of the inner class directly without friendship, though rules vary slightly by compiler context; standard practice is public access).
-
Scope: It is a limited scope class, visible mainly inside the outer class.
- Instantiation Outside: We can create objects of the inner class outside the outer class using the scope resolution operator
::, only if the inner class is declared public.
class Outer {
public:
void fun() {
i.display(); // Outer accessing Inner via object
}
class Inner {
public:
void display() {
std::cout << "Display of Inner" << std::endl;
}
};
Inner i; // Outer class containing an object of Inner
};
int main() {
// Object creation in main
Outer::Inner i;
i.display();
}
Summary of Key Differences
- Friend Class: Can access private members of another class upon its object.
- Static Functions: Are functions of the class (global scope within class namespace), not tied to an instance.
- Friend Functions: Are global functions (not members) granted special access.
- Invocation: Static member functions can be called using the Class Name or an Object.
- Purpose: Static members are primarily used for providing information about the class or managing shared state.