ఆపరేటర్ ఓవర్లోడింగ్ & Friends
కంప్యూటర్ ప్రోగ్రామింగ్ భాషల్లో గణిత సమీకరణాలు చదవడానికి ఎంత సహజంగా ఉంటే కోడ్ అంత సులభంగా అర్థమవుతుంది. ఉదాహరణకు రెండు సంక్లిష్ట సంఖ్యలను లేదా 3D వెక్టర్లను కూడటానికి v1.addVector(v2).multiplyScalar(5) అని రాసే బదులు, సాధారణ సంఖ్యల వలె (v1 + v2) * 5 అని రాయగలిగితే ఎంత అద్భుతంగా ఉంటుంది? ఈ మ్యాజిక్ను సాధ్యం చేసే C++ విశిష్ట లక్షణమే ఆపరేటర్ ఓవర్లోడింగ్ (Operator Overloading).
C++ మనకు ప్రాథమిక ఆపరేటర్లైన +, -, *, / లతో పాటు, ఇన్పుట్/అవుట్పుట్ స్ట్రీమ్లైన <<, >>, అర్రే ఇండెక్సింగ్ కోసం [], ఫంక్టర్ల కొరకు (), మరియు ప్రైవేట్ వేరియబుల్స్ను సురక్షితంగా అనుసంధానించే friend ఫంక్షన్లను అందించింది. అంతేకాకుండా Modern C++20 లో ప్రవేశపెట్టిన విప్లవాత్మకమైన త్రీ-వే కంపారిజన్ ఆపరేటర్ (<=> Spaceship Operator) గురించి క్షుణ్ణంగా తెలుసుకుందాం!
ఈ సమగ్ర మాస్టర్క్లాస్లో మనం Binary & Unary Operators, Member vs Non-Member Overloading, Stream Chaining, Subscript Access Safety, మరియు పూర్తి స్థాయి "Enterprise High-Performance 3D Vector Math & Physics Simulation Engine" ప్రాజెక్ట్ను లైవ్గా నిర్మించి నైపుణ్యం సాధిద్దాం!
1 ఆపరేటర్ ఓవర్లోడింగ్ అంటే ఏమిటి? ఎందుకు అవసరం? (Intuitive User-Defined Types)
ఆపరేటర్ ఓవర్లోడింగ్ (Operator Overloading) అంటే ఏమిటి? C++ లో ఇప్పటికే ఉన్న ఆపరేటర్లకు (ఉదాహరణకు +, -, ==, <<) మనం సృష్టించిన యూజర్-డిఫైన్డ్ క్లాసెస్ మరియు స్ట్రక్చర్లపై పనిచేయడానికి సరికొత్త అర్థాన్ని (Custom Behavior) అందించే ప్రక్రియను ఆపరేటర్ ఓవర్లోడింగ్ అంటారు.
దీనివల్ల ప్రయోజనాలు ఏమిటి?
- సహజమైన సింటాక్స్ (Intuitive Syntax): సంక్లిష్టమైన మెథడ్ కాల్స్ లేకుండా గణిత సూత్రాల వలె క్లీన్ కోడ్ రాయవచ్చు.
- స్టాండర్డ్ లైబ్రరీ ఇంటిగ్రేషన్: మన స్వంత క్లాస్ ఆబ్జెక్టులను నేరుగా
std::cout << myObjectద్వారా కన్సోల్పై ముద్రించవచ్చు.
1.
. (Dot - Member Access Operator)2.
.* (Pointer to Member Operator)3.
:: (Scope Resolution Operator)4.
?: (Ternary Conditional Operator)5.
sizeof (Size Query Operator)
2 ఆపరేటర్ ఫంక్షన్ సింటాక్స్ & గోల్డెన్ రూల్స్
ఆపరేటర్ను ఓవర్లోడ్ చేయడానికి మనం operator అనే ప్రత్యేక కీవర్డ్ను ఉపయోగిస్తాం:
ReturnType operator+(const ClassName& rhs) const;
ఆపరేటర్ ఓవర్లోడింగ్ యొక్క 3 ప్రాథమిక సూత్రాలు:
- ఆపరేటర్ ప్రెసిడెన్స్ మారదు:
+కంటే*ఎల్లప్పుడూ ముందే లెక్కించబడుతుంది. ఓవర్లోడ్ చేసినా ఈ ప్రాధాన్యతా క్రమం మారదు. - కొత్త ఆపరేటర్లను కనిపెట్టలేము: C++ లో లేని కొత్త గుర్తులను (ఉదాహరణకు Python లోని
**లేదా$) సృష్టించడం కుదరదు. - కనీసం ఒక్క ఆపరేండ్ యూజర్-డిఫైన్డ్ అయి ఉండాలి: రెండు ప్రిమిటివ్ పూర్ణాంకాల మధ్య (
int + int) పనితీరును మార్చడం అసాధ్యం.
3 అరిథ్మెటిక్ బైనరీ ఆపరేటర్లు (+, -, *)
రెండు సంక్లిష్ట సంఖ్యలను (Complex Numbers: $Real + i \cdot Imag$) కూడటానికి లేదా తీసివేయడానికి బైనరీ ఆపరేటర్లను ఎలా ఓవర్లోడ్ చేయాలో క్రింది ఉదాహరణలో చూడండి:
#include <iostream>
class ComplexNumber {
public:
double real;
double imag;
ComplexNumber(double r = 0.0, double i = 0.0) : real(r), imag(i) {}
// Binary + Operator Overloading (Member Function)
ComplexNumber operator+(const ComplexNumber& rhs) const {
return ComplexNumber(this->real + rhs.real, this->imag + rhs.imag);
}
// Binary - Operator Overloading
ComplexNumber operator-(const ComplexNumber& rhs) const {
return ComplexNumber(this->real - rhs.real, this->imag - rhs.imag);
}
void display() const {
std::cout << real << " + " << imag << "i\n";
}
};
int main() {
ComplexNumber c1(4.5, 3.2);
ComplexNumber c2(1.5, 2.8);
// సహజమైన గణిత సంకలనం!
ComplexNumber sum = c1 + c2; // అంతర్గతంగా c1.operator+(c2) గా మారుతుంది!
ComplexNumber diff = c1 - c2;
std::cout << "c1 + c2 మొత్తం: "; sum.display();
std::cout << "c1 - c2 తేడా: "; diff.display();
return 0;
}
4 కంపారిజన్ ఆపరేటర్లు (==, !=) & Modern C++20 Spaceship Operator (<=>)
రెండు ఆబ్జెక్టులు సమానమా కాదా అని పోల్చడానికి == మరియు != ఆపరేటర్లను ఉపయోగిస్తాం.
Modern C++20 Spaceship Operator (<=> Three-Way Comparison):
పూర్వపు C++ లో మీరు ఆబ్జెక్టులను సార్టింగ్ చేయడానికి ==, !=, <, <=, >, >= మొత్తం 6 ఫంక్షన్లను విడివిడిగా రాయాల్సి వచ్చేది! కానీ C++20 లో auto operator<=>(const MyClass&) const = default; అని ఒక్క లైన్ రాస్తే చాలు — కంపైలర్ స్వయంచాలకంగా మొత్తం 6 కంపారిజన్లను ఆప్టిమైజ్ చేసి ఆటో-జనరేట్ చేస్తుంది!
#include <iostream>
class Dimension {
public:
int length;
int breadth;
Dimension(int l, int b) : length(l), breadth(b) {}
// Equality Operator
bool operator==(const Dimension& rhs) const {
return (length == rhs.length && breadth == rhs.breadth);
}
bool operator!=(const Dimension& rhs) const {
return !(*this == rhs); // == పై ఆధారపడి సులభంగా రీయూజ్!
}
};
int main() {
Dimension d1(10, 20);
Dimension d2(10, 20);
Dimension d3(15, 30);
std::cout << "d1 == d2? " << (d1 == d2 ? "సమానం (True)" : "అసమానం (False)") << "\n";
std::cout << "d1 != d3? " << (d1 != d3 ? "అసమానం (True)" : "సమానం (False)") << "\n";
return 0;
}
5 స్ట్రీమ్ ఇన్సర్షన్ & ఎక్స్ట్రాక్షన్ ఆపరేటర్లు (<< మరియు >>)
మన స్వంత ఆబ్జెక్ట్ను std::cout << obj; అని ప్రింట్ చేయాలంటే operator<< ను ఓవర్లోడ్ చేయాలి.
ముఖ్యమైన టెక్నికల్ రహస్యం:
std::cout << obj; సమీకరణంలో ఎడమవైపు ఉన్న ఆపరేండ్ std::cout (Type: std::ostream). అది మన క్లాస్ కాదు! కాబట్టి ఈ ఆపరేటర్ను మన క్లాస్ లోపల మెంబర్ ఫంక్షన్గా రాయడం అసాధ్యం!
దీనిని తప్పనిసరిగా నాన్-మెంబర్ friend ఫంక్షన్గా మాత్రమే డిక్లేర్ చేయాలి:
friend std::ostream& operator<<(std::ostream& os, const MyClass& obj);
#include <iostream>
#include <string>
class StockItem {
private:
std::string itemName;
double price;
int stockQuantity;
public:
StockItem(std::string name, double p, int qty) : itemName(name), price(p), stockQuantity(qty) {}
// friend stream insertion operator
friend std::ostream& operator<<(std::ostream& os, const StockItem& item) {
os << "[ఉత్పత్తి: " << item.itemName << " | ధర: ₹ " << item.price << " | నిల్వ: " << item.stockQuantity << " యూనిట్లు]";
return os; // చైనింగ్ (cout << a << b) కొరకు os రిటర్న్ చేయాలి!
}
};
int main() {
StockItem item1("Sony PlayStation 5", 54990.0, 15);
StockItem item2("LG OLED 4K TV", 89990.0, 8);
// అందమైన స్ట్రీమ్ ప్రింటింగ్!
std::cout << item1 << "\n" << item2 << "\n";
return 0;
}
6 friend ఫంక్షన్లు & friend క్లాసెస్ (The Trusted VIP Pass)
ఎన్క్యాప్సులేషన్ సూత్రం ప్రకారం క్లాస్ లోని ప్రైవేట్ వేరియబుల్స్ను బయటి ఫంక్షన్లు తాకలేవు. కానీ కొన్ని సందర్భాల్లో (ఉదాహరణకు రెండు విభిన్న క్లాసులు పరస్పరం వేగంగా సంభాషించుకోవడానికి లేదా పైన చూసిన operator<< కొరకు) బయటి ఫంక్షన్కు ప్రైవేట్ డేటాను చూసే అనుమతి ఇవ్వాల్సి వస్తుంది.
దాని కోసమే C++ friend కీవర్డ్ను అందించింది. ఒక క్లాస్ లోపల friend void inspect(const MyClass& obj); అని రాస్తే, ఆ ఫంక్షన్ ఆ క్లాస్ యొక్క ప్రైవేట్ మెంబర్లను స్వేచ్ఛగా యాక్సెస్ చేయగలదు.
#include <iostream>
#include <string>
class BankVault; // ఫార్వర్డ్ డిక్లరేషన్
class VaultAuditor {
public:
void auditAccount(const BankVault& vault);
};
class BankVault {
private:
std::string secretKey = "VAULT_SECRET_9876";
double reserveCash = 50000000.0;
// VaultAuditor క్లాస్ను అధికారిక 'friend' గా ప్రకటిస్తున్నాం!
friend class VaultAuditor;
};
void VaultAuditor::auditAccount(const BankVault& vault) {
// friend అయినందున ప్రైవేట్ డేటాను నేరుగా చదవగలదు!
std::cout << " 🔍 [RBI ఆడిట్] రహస్య కీ: " << vault.secretKey << "\n";
std::cout << " 💰 [RBI ఆడిట్] వాల్ట్ నగదు నిల్వ: ₹ " << vault.reserveCash << "\n";
}
int main() {
BankVault vault;
VaultAuditor auditor;
auditor.auditAccount(vault);
return 0;
}
7 మెంబర్ వర్సెస్ నాన్-మెంబర్ ఆపరేటర్లు (Left-hand Operand Symmetry)
ఆలోచించండి: Complex c = c1 * 2.0; అని రాస్తే, c1.operator*(2.0) కాల్ అవుతుంది కాబట్టి సవ్యంగా పనిచేస్తుంది.
కానీ గణితంలో క్రమం మారినా ఒకే ఫలితం రావాలి కదా: Complex c = 2.0 * c1; అని రాస్తే?
ఇక్కడ ఎడమవైపు 2.0 (double) ఉంది! double ప్రిమిటివ్ టైప్ కాబట్టి దానికి మనం operator* రాయలేము!
పరిష్కారం: నాన్-మెంబర్ ఫ్రెండ్ ఫంక్షన్ను ఉపయోగించి friend Complex operator*(double lhs, const Complex& rhs) అని రాయడం ద్వారా సమరూపతను (Symmetry) సాధించవచ్చు!
8 సబ్స్క్రిప్ట్ ఆపరేటర్ ఓవర్లోడింగ్ (operator[])
మనం ఒక కస్టమ్ కలెక్షన్ లేదా అర్రేను నిర్మించినప్పుడు దాని మూలకాలను సాధారణ అర్రే వలె myList[3] అని చదవడానికి మరియు సవరించడానికి operator[] ను ఓవర్లోడ్ చేస్తాం.
ఎల్లప్పుడూ రెండు వెర్షన్లు అందించడం ఇండస్ట్రీ బెస్ట్ ప్రాక్టీస్:
- Non-const వెర్షన్: విలువను మార్చడానికి (Mutate) రిఫరెన్స్ రిటర్న్ చేస్తుంది:
T& operator[](size_t index); - Const వెర్షన్: రీడ్-ఓన్లీ సందర్భాల కొరకు కాన్స్ట్ రిఫరెన్స్ రిటర్న్ చేస్తుంది:
const T& operator[](size_t index) const;
#include <iostream>
#include <stdexcept>
class SafeBuffer {
private:
int data[5] = {10, 20, 30, 40, 50};
public:
int& operator[](size_t index) {
if (index >= 5) {
throw std::out_of_range("❌ ఎర్రర్: బఫర్ బౌండరీ దాటిపోయింది!");
}
return data[index];
}
const int& operator[](size_t index) const {
if (index >= 5) {
throw std::out_of_range("❌ ఎర్రర్: బఫర్ బౌండరీ దాటిపోయింది!");
}
return data[index];
}
};
int main() {
SafeBuffer buf;
std::cout << "buf[2] పాత విలువ: " << buf[2] << "\n";
buf[2] = 999;
std::cout << "buf[2] కొత్త విలువ: " << buf[2] << "\n";
return 0;
}
9 యునరీ ఆపరేటర్లు: ప్రీఫిక్స్ వర్సెస్ పోస్ట్ఫిక్స్ ఇంక్రిమెంట్ (++obj vs obj++)
C++ కంపైలర్ ప్రీఫిక్స్ ఇంక్రిమెంట్ (++x) మరియు పోస్ట్ఫిక్స్ ఇంక్రిమెంట్ (x++) మధ్య ఎలా తేడాను గుర్తిస్తుంది?
- ప్రీఫిక్స్ (
++obj): ఎటువంటి ఆర్గుమెంట్లు ఉండవు:MyClass& operator++();. ఇది తక్షణమే విలువను పెంచి ప్రస్తుత ఆబ్జెక్ట్ రిఫరెన్స్ను (*this) రిటర్న్ చేస్తుంది. - పోస్ట్ఫిక్స్ (
obj++): కంపైలర్ తేడాను గుర్తించడానికి ఒక డమ్మీintపారామీటర్ను తీసుకుంటుంది:MyClass operator++(int);.
#include <iostream>
class StepCounter {
private:
int steps;
public:
StepCounter(int s = 0) : steps(s) {}
// Prefix Increment: ++counter
StepCounter& operator++() {
++steps;
return *this; // రిఫరెన్స్ రిటర్న్ - సూపర్ ఫాస్ట్!
}
// Postfix Increment: counter++ (డమ్మీ int తో)
StepCounter operator++(int) {
StepCounter temp = *this; // పాత కాపీని భద్రపరచడం
++steps; // ప్రస్తుత విలువ పెంపు
return temp; // పాత కాపీని రిటర్న్
}
int getSteps() const { return steps; }
};
int main() {
StepCounter c(10);
StepCounter pre = ++c; // c -> 11, pre -> 11
std::cout << "Prefix తర్వాత c: " << c.getSteps() << " | pre: " << pre.getSteps() << "\n";
StepCounter post = c++; // post -> 11, c -> 12
std::cout << "Postfix తర్వాత c: " << c.getSteps() << " | post: " << post.getSteps() << "\n";
return 0;
}
10 ఫంక్షన్ కాల్ ఆపరేటర్ (operator()) & ఫంక్టర్లు (Functors)
ఒక క్లాస్ ఆబ్జెక్ట్ను ఒక సాధారణ ఫంక్షన్ లాగా myObj(10, 20) అని పిలవడానికి operator() ను ఓవర్లోడ్ చేస్తాం.
ఇలా ఫంక్షన్ లా ప్రవర్తించే ఆబ్జెక్టులను C++ లో ఫంక్టర్లు (Functors లేదా Function Objects) అంటారు.
#include <iostream>
#include <vector>
#include <algorithm>
// Functor Class
class ThresholdFilter {
private:
int minThreshold;
public:
ThresholdFilter(int threshold) : minThreshold(threshold) {}
// Function call operator () overloading
bool operator()(int value) const {
return value >= minThreshold;
}
};
int main() {
std::vector<int> scores = {45, 82, 91, 33, 76, 58, 99};
ThresholdFilter passFilter(60); // 60 కంటే ఎక్కువ ఉన్నవి పాస్!
int passedStudents = std::count_if(scores.begin(), scores.end(), passFilter);
std::cout << "మొత్తం విద్యార్థులు: " << scores.size() << "\n";
std::cout << "60 మార్కులకు పైగా సాధించిన వారు: " << passedStudents << "\n";
return 0;
}
11 ఆపరేటర్ ఓవర్లోడింగ్లో చేయకూడని తప్పులు (Anti-Patterns)
-
ఆపరేటర్ యొక్క సహజార్థాన్ని మార్చడం:
+ఆపరేటర్తో తీసివేత చేయడం లేదా డాక్యుమెంట్ డిలీట్ చేయడం వంటి విరుద్ధమైన పనులు ఎప్పుడూ చేయకూడదు. -
షార్ట్-సర్క్యూట్ ఆపరేటర్లను ఓవర్లోడ్ చేయడం: లాజికల్ ఆపరేటర్లు (
&&,||) ఓవర్లోడ్ చేస్తే వాటి సహజ షార్ట్-సర్క్యూట్ ఎవాల్యుయేషన్ లక్షణం నశించి తీవ్రమైన బగ్స్ వస్తాయి.
12 రియల్-వరల్డ్ ప్రాజెక్ట్: Enterprise High-Performance 3D Vector Math & Physics Engine
నిజ జీవితంలో Unreal Engine, Unity, నాసా శాటిలైట్ ట్రాకింగ్ సిస్టమ్స్ మరియు 3D కంప్యూటర్ గ్రాఫిక్స్ ఇంజిన్లు మిలియన్ల కొద్దీ 3D స్పేస్ కోఆర్డినేట్స్ ($x, y, z$) లపై వెక్టర్ అంకగణితాన్ని నిరంతరం లెక్కిస్తాయి.
ఈ సమగ్ర ప్రాజెక్ట్లో మనం +, -, * (Scalar & Dot Product), ==, [] సబ్స్క్రిప్ట్, మరియు << స్ట్రీమ్ అవుట్పుట్తో కూడిన ఎంటర్ప్రైజ్ 3D వెక్టర్ ఫిజిక్స్ ఇంజిన్ ను నిర్మిస్తున్నాం:
#include <iostream>
#include <cmath>
#include <iomanip>
class Vector3D {
private:
double coords[3]; // 0: x, 1: y, 2: z
public:
Vector3D(double x = 0.0, double y = 0.0, double z = 0.0) {
coords[0] = x;
coords[1] = y;
coords[2] = z;
}
// 1. Array Subscript Operator ([]) Overloading
double& operator[](size_t index) { return coords[index]; }
const double& operator[](size_t index) const { return coords[index]; }
// 2. Binary Vector Addition (+)
Vector3D operator+(const Vector3D& rhs) const {
return Vector3D(coords[0] + rhs[0], coords[1] + rhs[1], coords[2] + rhs[2]);
}
// 3. Binary Vector Subtraction (-)
Vector3D operator-(const Vector3D& rhs) const {
return Vector3D(coords[0] - rhs[0], coords[1] - rhs[1], coords[2] - rhs[2]);
}
// 4. Scalar Multiplication: Vector * scalar
Vector3D operator*(double scalar) const {
return Vector3D(coords[0] * scalar, coords[1] * scalar, coords[2] * scalar);
}
// 5. Symmetric Non-member Friend: scalar * Vector
friend Vector3D operator*(double scalar, const Vector3D& v) {
return v * scalar; // రీ-యూజ్!
}
// 6. Dot Product Multiplication: Vector * Vector
double dot(const Vector3D& rhs) const {
return (coords[0] * rhs[0]) + (coords[1] * rhs[1]) + (coords[2] * rhs[2]);
}
// 7. Magnitude (Vector Length)
double magnitude() const {
return std::sqrt(dot(*this));
}
// 8. Equality Operator
bool operator==(const Vector3D& rhs) const {
return (coords[0] == rhs[0] && coords[1] == rhs[1] && coords[2] == rhs[2]);
}
// 9. Stream Insertion Operator (<<)
friend std::ostream& operator<<(std::ostream& os, const Vector3D& v) {
os << "Vector3D(" << v[0] << ", " << v[1] << ", " << v[2] << ")";
return os;
}
};
int main() {
std::cout << "=======================================================================\n";
std::cout << "🚀 [ENTERPRISE 3D VECTOR MATH & ASTROPHYSICS ENGINE RUNNING]\n";
std::cout << "=======================================================================\n";
Vector3D position(10.0, 20.0, 5.0);
Vector3D velocity(2.5, -1.0, 4.0);
std::cout << "ప్రారంభ స్థానం (Position) : " << position << "\n";
std::cout << "ప్రస్తుత వేగం (Velocity) : " << velocity << "\n";
// 1 సెకను తర్వాతి స్థానం: pos + vel
Vector3D nextPos = position + velocity;
std::cout << "తర్వాతి స్థానం (Next Pos) : " << nextPos << "\n";
// స్కేలార్ గుణకారం (3x Velocity Boost): v * 3
Vector3D boosted = velocity * 3.0;
std::cout << "3x బూస్ట్ వేగం (Boosted) : " << boosted << "\n";
// సిమెట్రిక్ నాన్-మెంబర్ గుణకారం: 2.0 * v
Vector3D doubleSpeed = 2.0 * velocity;
std::cout << "డబుల్ స్పీడ్ (2.0 * vel) : " << doubleSpeed << "\n";
// డాట్ ప్రొడక్ట్ గణన
double dotProduct = position.dot(velocity);
std::cout << "స్థానం మరియు వేగం డాట్ ప్రొడక్ట్: " << dotProduct << "\n";
std::cout << "వేగం యొక్క పరిమాణం (Speed): " << std::fixed << std::setprecision(2) << velocity.magnitude() << " m/s\n";
std::cout << "=======================================================================\n";
std::cout << "✅ ఆపరేటర్ ఓవర్లోడింగ్ తో ఫిజిక్స్ వెక్టర్ సిమ్యులేషన్ విజయవంతమైంది!\n";
std::cout << "=======================================================================\n";
return 0;
}
13 సారాంశం & ఇంటరాక్టివ్ క్విజ్ (Summary & Self-Check Quizzes)
📌 ఈ అధ్యాయంలో నేర్చుకున్న ప్రధాన అంశాలు:
- Operator Overloading: యూజర్-డిఫైన్డ్ టైప్స్ కోసం C++ ఆపరేటర్లకు కస్టమ్ బిహేవియర్ అందించే శక్తి.
- Non-overloadable Operators:
.,.*,::,?:, మరియుsizeofలను ఓవర్లోడ్ చేయలేము. - Stream Overloading:
<<మరియు>>లను ఎల్లప్పుడూ నాన్-మెంబర్friendఫంక్షన్లుగానే రాయాలి. - Symmetry:
2 * objవంటి సందర్భాల కోసం నాన్-మెంబర్ ఫ్రెండ్ ఫంక్షన్లు తప్పనిసరి. - Subscript
operator[]: సేఫ్ బౌండ్స్ చెకింగ్తో అర్రే యాక్సెస్ అందించడం. - Prefix vs Postfix: ప్రీఫిక్స్
++xఫాస్ట్ (నో డమ్మీ పారామీటర్); పోస్ట్ఫిక్స్x++కాపీ రిటర్న్ చేస్తుంది (డమ్మీintపారామీటర్). - C++20 Spaceship Operator:
<=>ద్వారా మొత్తం 6 కంపారిజన్లను ఆటోమేటిక్గా రూపొందించడం.
🧠 మీ అవగాహనను పరీక్షించుకోండి (5 Interactive Quizzes):
ప్రశ్న 1: C++ లో స్ట్రీమ్ ఇన్సర్షన్ ఆపరేటర్ operator<< ను క్లాస్ మెంబర్ ఫంక్షన్గా ఎందుకు రాయలేము?
std::ostream (std::cout), మన క్లాస్ కాదు!వివరణ: మెంబర్ ఫంక్షన్ కావాలంటే ఎడమవైపు ఉన్న ఆబ్జెక్ట్ మన క్లాస్ అయి ఉండాలి (ఉదాహరణకు
obj << cout లాగా). కానీ మనం cout << obj అని రాస్తాం కాబట్టి దీనిని నాన్-మెంబర్ ఫ్రెండ్ ఫంక్షన్గా మాత్రమే రాయగలం.
ప్రశ్న 2: కంపైలర్ ప్రీఫిక్స్ ఇంక్రిమెంట్ (++x) మరియు పోస్ట్ఫిక్స్ ఇంక్రిమెంట్ (x++) మధ్య తేడాను ఎలా గుర్తిస్తుంది?
int పారామీటర్ ఉండటం ద్వారా!వివరణ:
operator++() అనేది ప్రీఫిక్స్ (ఆర్గుమెంట్లు లేవు); operator++(int) అనేది పోస్ట్ఫిక్స్. ఆ int పారామీటర్కు విలువతో సంబంధం లేదు, కేవలం కంపైలర్ గుర్తుపట్టడానికి మాత్రమే అది ఉంటుంది.
ప్రశ్న 3: క్రింది వాటిలో C++ లో ఓవర్లోడ్ చేయడానికి అనుమతించబడని ఆపరేటర్ ఏది?
:: (Scope Resolution Operator) లేదా . (Dot Operator)!వివరణ: C++ స్టాండర్డ్ ప్రకారం
., .*, ::, ?:, మరియు sizeof ఆపరేటర్లను ఓవర్లోడ్ చేయడం కంపైలర్ భద్రత దృష్ట్యా పూర్తిగా నిషేధించబడింది.
ప్రశ్న 4: Modern C++20 లో Spaceship Operator (<=>) తీసుకువచ్చిన ప్రధాన విప్లవం ఏమిటి?
==, !=, <, <=, >, >=) ఆటోమేటిక్గా రూపొందించడం!వివరణ: పూర్వం 6 వేర్వేరు ఆపరేటర్ ఫంక్షన్లు రాయాల్సి వచ్చేది. C++20 లో
auto operator<=>(const T&) const = default; రాస్తే కంపైలర్ వాటన్నింటినీ స్వయంచాలకంగా సృష్టిస్తుంది.
ప్రశ్న 5: C++ లో friend ఫంక్షన్ అంటే ఏమిటి? అది ఎన్క్యాప్సులేషన్ను నాశనం చేస్తుందా?
వివరణ: బయటి ఫంక్షన్ బలవంతంగా ప్రైవేట్ డేటాను దొంగిలించదు. క్లాస్ డెవలపర్ తన క్లాస్ లోపల స్పష్టంగా
friend అని ప్రకటించినప్పుడు మాత్రమే ఆ అనుమతి లభిస్తుంది.
ఈ ప్రాజెక్ట్ను లైవ్గా మన కంపైలర్లో రన్ చేయండి!
ఎటువంటి లోకల్ సెటప్ లేకుండా, బ్రౌజర్లోనే నేరుగా Modern C++ (GCC 13 / C++20) కంపైలర్లో ఈ కోడ్ను ఎగ్జిక్యూట్ చేసి రన్టైమ్ అవుట్పుట్ను తనిఖీ చేయండి.