A friend function in C++ is a special type of function that is not a member of a class but has the ability to access its private and protected members. This feature is particularly useful when you need to perform operations that require access to the internal data of a class without making the function a member of that class.
Access Privileges: A friend function can access all members (private, protected, and public) of the class it is declared as a friend of. This allows for greater flexibility in manipulating class data from outside its scope.
Declaration: To declare a function as a friend, you use the friend keyword inside the class definition. The declaration can be placed in any section of the class (public, private, or protected)1.
Scope: A friend function does not belong to the class for which it is designated as a friend. Therefore, it cannot be called using the class name but must be invoked like any other global function1.
Object Access: Although a friend function can access private data, it must do so through an object instance using the dot operator (.).
Multiple Friendships: A single function can be declared as a friend in multiple classes, allowing it to access their private members1.
Here’s how you declare a friend function:
class ClassName {
friend returnType functionName(parameters);
// Other members
};
Example:
#include <iostream>
using namespace std;
class Box {
private:
int length;
public:
Box(int l) : length(l) {}
// Declare friend function
friend void printLength(Box b);
};
// Friend function definition
void printLength(Box b) {
cout << "Length of box: " << b.length << endl; // Accessing private member
}
int main() {
Box box(10);
printLength(box); // Call to friend function
return 0;
}
In C++, a friend class is a class that has access to the private and protected members of another class. This relationship allows all member functions of the friend class to access the non-public members of the class that declares it as a friend. This feature is useful for tightly coupled classes that need to work closely together.
Access Control: When one class declares another as a friend, all member functions of the friend class can access the private and protected members of the other class. However, this access is not mutual unless explicitly declared.
Declaration: To declare a friend class, you use the friend keyword followed by the class name within the body of the class that grants friendship.
Non-Mutual Friendship: Friendship is not reciprocal. If Class A declares Class B as a friend, Class B can access Class A's members, but Class A cannot access Class B's members unless Class B also declares Class A as a friend.
Here’s how you declare a friend class:
class ClassB; // Forward declaration
class ClassA {
friend class ClassB; // Declaring ClassB as a friend
// Other members
};
Here’s an example demonstrating the use of a friend class:
#include <iostream>
using namespace std;
class ClassB; // Forward declaration
class ClassA {
private:
int numA;
public:
ClassA() : numA(12) {}
// Declaring ClassB as a friend
friend class ClassB;
};
class ClassB {
private:
int numB;
public:
ClassB() : numB(1) {}
// Function to add numA from ClassA and numB from ClassB
int add(ClassA& objA) {
return objA.numA + numB; // Accessing private member of ClassA
}
};
int main() {
ClassA objectA;
ClassB objectB;
cout << "Sum: " << objectB.add(objectA); // Outputs: Sum: 13
return 0;
}
Operator overloading in C++ allows developers to redefine the behavior of standard operators (like +, -, *, etc.) for user-defined types such as classes and structures. This feature enhances the expressiveness of the language, enabling operators to work with objects in a way that is intuitive and consistent with their traditional meanings.
Definition: Operator overloading is a form of compile-time polymorphism that enables operators to have user-defined meanings when applied to class objects. For example, the + operator can be overloaded to concatenate two string objects or add two complex numbers.
Syntax: The syntax for overloading an operator is similar to that of a function, using the operator keyword followed by the operator symbol. The general form is:
returnType operator symbol(arguments) {
// implementation
}
Here, returnType specifies what the function returns, symbol is the operator being overloaded, and arguments are the parameters for the function.
Can we overload all operators?
Almost all operators can be overloaded except few. Following is the list of operators that cannot be overloaded.
. (dot)
::
?:
sizeof
Example:
#include <iostream>
using namespace std;
class Complex
{
private:
int real, imag;
public:
Complex(int r = 0, int i = 0)
{
real = r;
imag = i;
}
// This is automatically called when '+' is used with
// between two Complex objects
Complex operator +(Complex const &obj)
{
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
void print() { cout << real << " + " << imag << 'i'<< endl; }
};
int main()
{
Complex c1(10, 5), c2(2, 4);
Complex c3 = c1 + c2;
c3.print();
}
Important points about operator overloading
For operator overloading to work, at least one of the operands must be a user defined class object.
Assignment Operator: Compiler automatically creates a default assignment operator with every class. The default assignment operator does assign all members of right side to the left side and works fine most of the cases (this behavior is same as copy constructor).
Conversion Operator: We can also write conversion operators that can be used to convert one type to another type. Overloaded conversion operators must be a member method. Other operators can either be member method or global method.
Any constructor that can be called with a single argument works as a conversion constructor, means it can also be used for implicit conversion to the class being constructed.
Example:
#include <iostream>
using namespace std;
class add{
int a;
public:
add(int a1){
a=a1;
}
// Conversion operator: return int value
operator int(){
return (int) a;
}
};
int operator +(add &num1,add &num2){
return num1 * num2;
}
int main(){
add a=2;
add b=7;
cout << a+b << endl;
return 0;
}