()
The function call operator allows objects to be used as if they were functions. Objects that implement this operator are called "functors."
class Complex {
private:
int real;
int imag;
public:
Complex(int real = 0, int imag = 0) {
this->real = real;
this->imag = imag;
}
// Function call operator overloading
void operator()(int real, int imag) {
this->real = real;
this->imag = imag;
}
void printRecord() {
cout << "Real Number: " << this->real << endl;
cout << "Imag Number: " << this->imag << endl;
}
};
int main() {
Complex c1;
c1(10, 20); // Using the object like a function: c1.operator()(10, 20)
c1.printRecord(); // Output: Real Number: 10, Imag Number: 20
return 0;
}
Benefits of Functors:
->
The arrow operator is used to create smart pointer-like objects that provide automatic resource management.
class Array {
private:
int* data;
int size;
public:
Array(int size) : size(size) {
data = new int[size]();
}
void acceptRecord() {
cout << "Enter " << size << " elements: ";
for(int i = 0; i < size; i++)
cin >> data[i];
}
void printRecord() {
cout << "Array elements: ";
for(int i = 0; i < size; i++)
cout << data[i] << " ";
cout << endl;
}
~Array() {
delete[] data;
}
};
class AutoPtr {
private:
Array* ptr;
public:
AutoPtr(Array* ptr) : ptr(ptr) {}
// Arrow operator overloading
Array* operator->() {
return ptr;
}
~AutoPtr() {
delete ptr; // Automatic cleanup
}
};
int main() {
// No need to call delete manually
AutoPtr obj(new Array(3));
obj->acceptRecord(); // Equivalent to: obj.operator->()->acceptRecord();
obj->printRecord(); // Equivalent to: obj.operator->()->printRecord();
return 0;
}
Conversion functions allow converting between user-defined types and fundamental types. There are three main types of conversion functions:
Converts from fundamental type to user-defined type:
class Complex {
private:
int real;
int imag;
public:
// Single parameter constructor acts as conversion function
Complex(int r) : real(r), imag(0) {
cout << "Conversion from int to Complex" << endl;
}
Complex(int r, int i) : real(r), imag(i) {}
void printRecord() {
cout << "Real: " << real << ", Imag: " << imag << endl;
}
};
int main() {
int number = 10;
Complex c1 = number; // Implicitly calls Complex(number)
c1.printRecord(); // Output: Real: 10, Imag: 0
return 0;
}
Using explicit
keyword to prevent implicit conversion:
class Complex {
private:
int real;
int imag;
public:
// Prevents implicit conversion
explicit Complex(int r) : real(r), imag(0) {
cout << "Explicit conversion from int to Complex" << endl;
}
// Other methods...
};
int main() {
int number = 10;
// Complex c1 = number; // Error: implicit conversion not allowed
Complex c1(number); // Explicit conversion is allowed
Complex c2 = static_cast<Complex>(number); // Also allowed
return 0;
}
Allows assignment from one type to another: