ఇన్హెరిటెన్స్ (Inheritance)

🌐 Modern C++ (C++20/C++17) 🟢 Chapter 15 of 20 📂 Phase 04: ఆబ్జెక్ట్ ఓరియెంటెడ్ OOP 📅 2026 Edition
📌 Covered in this chapter: సింగిల్, మల్టీలెవల్, మల్టిపుల్ ఇన్హెరిటెన్స్ · protected యాక్సెస్ · Constructor Chaining · Diamond Problem & Virtual Base Classes

నిజ జీవితంలో పిల్లలు తమ తల్లిదండ్రుల నుండి శారీరక రూపాన్ని, తెలివితేటలను మరియు ఆస్తులను వారసత్వంగా పొందుతారు. సరిగ్గా ఇదే సూత్రాన్ని సాఫ్ట్‌వేర్ ఇంజనీరింగ్‌కు అన్వయించిన విప్లవాత్మక ఆబ్జెక్ట్ ఓరియెంటెడ్ భావనే ఇన్హెరిటెన్స్ (Inheritance - వారసత్వం). ఇప్పటికే ఉన్న ఒక క్లాస్ యొక్క లక్షణాలను మరియు ఫంక్షన్లను మళ్లీ రాయకుండా (Zero Code Duplication), వాటిని పొడిగిస్తూ సరికొత్త క్లాసులను నిర్మించడానికి ఇది ఉపయోగపడుతుంది.

ఇతర ఆధునిక భాషల కంటే C++ ఇన్హెరిటెన్స్ వ్యవస్థ ఎంతో శక్తివంతమైనది. ఎందుకంటే C++ మాత్రమే మల్టిపుల్ ఇన్హెరిటెన్స్ (Multiple Inheritance) కు పూర్తి స్థాయి మద్దతును అందిస్తుంది! అయితే బహుళ బేస్ క్లాసుల కలయిక వల్ల ఏర్పడే కుప్రసిద్ధమైన డైమండ్ ప్రాబ్లమ్ (The Diamond Problem) మరియు దానిని విచ్ఛిన్నం చేసే virtual Base Classes ఆర్కిటెక్చర్‌ను లోతుగా అవగతం చేసుకోవడం ప్రతి సీనియర్ సిస్టమ్స్ ప్రోగ్రామర్‌కు తప్పనిసరి.

ఈ సమగ్ర మాస్టర్‌క్లాస్‌లో మనం Single, Multilevel, Multiple & Hybrid Inheritance, Access Modes (public vs protected vs private), Constructor & Destructor Chaining ఎగ్జిక్యూషన్ ఆర్డర్, వర్చువల్ బేస్ క్లాస్ మెకానిక్స్, మరియు పూర్తి స్థాయి "Enterprise Defense & Aerospace Autonomous Combat Drone Fleet Engine" ప్రాజెక్ట్‌ను నిర్మించి నైపుణ్యం సాధిద్దాం!

1 ఇన్హెరిటెన్స్ అంటే ఏమిటి? ఎందుకు అవసరం? (Code Reusability & "Is-A" Relationship)

ఇన్హెరిటెన్స్ (Inheritance) అంటే ఏమిటి? ఇప్పటికే ఉన్న ఒక క్లాస్ (దీనిని Base Class లేదా Parent Class అంటారు) లోని ఫీచర్లు, వేరియబుల్స్ మరియు ఫంక్షన్లను మరొక కొత్త క్లాస్ (దీనిని Derived Class లేదా Child Class అంటారు) వారసత్వంగా స్వీకరించే ప్రక్రియను ఇన్హెరిటెన్స్ అంటారు.

సాఫ్ట్‌వేర్ అభివృద్ధిలో ఇన్హెరిటెన్స్ ఎందుకు అవసరం?

  1. కోడ్ పునర్వినియోగం (Code Reusability): ఒకే రకమైన కోడ్‌ను 10 వేర్వేరు క్లాసులలో పదే పదే కాపీ పేస్ట్ చేయకుండా, ఉమ్మడి కోడ్‌ను ఒక Base Class లో రాసి అందరూ వాడుకునేలా చేయవచ్చు.
  2. విస్తరణ సామర్థ్యం (Extensibility): ఇప్పటికే పనిచేస్తున్న పాత కోడ్‌ను మార్చకుండా, దానిపై కొత్త ఫీచర్లను సులభంగా జోడించవచ్చు (Open-Closed Principle).
  3. "Is-A" రిలేషన్‌షిప్: నిజ జీవిత సంబంధాలను సరిగ్గా ప్రతిబింబిస్తుంది:
    • Car is a Vehicle
    • SavingsAccount is a BankAccount
    • FighterJet is an Aircraft

2 C++ ఇన్హెరిటెన్స్ సింటాక్స్ & మెమరీ లేఅవుట్ (Base Subobject in RAM)

C++ లో ఇన్హెరిటెన్స్ చేయడానికి డిరైవ్డ్ క్లాస్ పేరు పక్కన కోలన్ (:) పెట్టి, Access Mode మరియు Base Class పేరును రాస్తాం:

class DerivedClass : public BaseClass {
    // అదనపు వేరియబుల్స్ & ఫంక్షన్లు
};
[Derived Class Memory Allocation in RAM (Contiguous Layout)]
+-------------------------------------------------------+
| Derived Class Object (e.g. ElectricCar) |
| +-------------------------------------------------+ |
| | Base Subobject (Vehicle) | |
| | - std::string vinNumber | |
| | - int currentSpeed | |
| +-------------------------------------------------+ |
| | Derived Specific Members | |
| | - int batteryPercentage | |
| | - double kilowattHours | |
| +-------------------------------------------------+ |
+-------------------------------------------------------+

పై ఆర్కిటెక్చర్ ప్రకారం: ఒక డిరైవ్డ్ క్లాస్ ఆబ్జెక్ట్ మెమరీలో సృష్టించబడినప్పుడు, దాని లోపల ముందుగా బేస్ క్లాస్ డేటా మెంబర్లు (Base Subobject) భద్రపరచబడి, వాటి కిందనే డిరైవ్డ్ క్లాస్ స్వంత మెంబర్లు కేటాయించబడతాయి.

3 Access Modes: public, protected, మరియు private ఇన్హెరిటెన్స్

చాలా మంది బిగినర్స్ class Derived : public Base లోని public ను సాధారణ పదం అనుకుంటారు. కానీ C++ లో ఇన్హెరిటెన్స్ మూడు వేర్వేరు మోడ్లలో సాధ్యమవుతుంది. ఇది బేస్ క్లాస్ మెంబర్లు చైల్డ్ క్లాస్‌లో ఎలా కనబడాలో నిర్దేశిస్తుంది:

బేస్ క్లాస్ మెంబర్ (Base Member) public ఇన్హెరిటెన్స్ తర్వాత protected ఇన్హెరిటెన్స్ తర్వాత private ఇన్హెరిటెన్స్ తర్వాత
public: public గానే ఉంటుంది protected గా మారుతుంది private గా మారుతుంది
protected: protected గానే ఉంటుంది protected గానే ఉంటుంది private గా మారుతుంది
private: ఎప్పటికీ అందుబాటులో ఉండదు (Hidden) ఎప్పటికీ అందుబాటులో ఉండదు (Hidden) ఎప్పటికీ అందుబాటులో ఉండదు (Hidden)
💡 గోల్డెన్ రూల్: 99% వాస్తవ ప్రాజెక్టులలో మనం public inheritance నే ఉపయోగిస్తాం! ఎందుకంటే ఇది మాత్రమే నిజమైన "Is-A" సంబంధాన్ని కాపాడుతుంది. private inheritance అనేది కేవలం కంపోజిషన్ (Has-A) వంటి అంతర్గత ఇంప్లిమెంటేషన్ వివరాల దాచివేతకు మాత్రమే వాడబడుతుంది.

4 సింగిల్ & మల్టీలెవల్ ఇన్హెరిటెన్స్ (Single & Multilevel Inheritance)

  1. సింగిల్ ఇన్హెరిటెన్స్ (Single Inheritance): ఒకే ఒక బేస్ క్లాస్ నుండి ఒకే ఒక డిరైవ్డ్ క్లాస్ పుట్టడం (ఉదాహరణ: Vehicle -> Car).
  2. మల్టీలెవల్ ఇన్హెరిటెన్స్ (Multilevel Inheritance): ఒక గొలుసుకట్టు వలె తాత నుండి తండ్రి, తండ్రి నుండి కొడుకు వరకు వారసత్వం కొనసాగడం (ఉదాహరణ: Device -> Computer -> Laptop).
multilevel_inheritance_demo.cpp
#include <iostream>
#include <string>

// లెవల్ 1: Base Class
class Device {
public:
    void powerOn() {
        std::cout << "  [Device] విద్యుత్ సరఫరా ఆన్ చేయబడింది.\n";
    }
};

// లెవల్ 2: Derived from Device
class Computer : public Device {
public:
    void bootOS() {
        std::cout << "  [Computer] ఆపరేటింగ్ సిస్టమ్ బూట్ అవుతోంది...\n";
    }
};

// లెవల్ 3: Derived from Computer (Multilevel)
class Laptop : public Computer {
public:
    void checkBattery() {
        std::cout << "  [Laptop] బ్యాటరీ నిల్వ: 92%\n";
    }
};

int main() {
    Laptop myLaptop;
    std::cout << "===== మల్టీలెవల్ ఇన్హెరిటెన్స్ ఫ్లో =====\n";
    myLaptop.powerOn();     // లెవల్ 1 ఫంక్షన్
    myLaptop.bootOS();      // లెవల్ 2 ఫంక్షన్
    myLaptop.checkBattery(); // లెవల్ 3 ఫంక్షన్
    return 0;
}

5 హైరార్కికల్ ఇన్హెరిటెన్స్ (Hierarchical Inheritance)

ఒకే ఒక్క ప్రధాన బేస్ క్లాస్ నుండి బహుళ వేర్వేరు చైల్డ్ క్లాసులు స్వతంత్రంగా పుట్టడాన్ని హైరార్కికల్ ఇన్హెరిటెన్స్ అంటారు.

ఉదాహరణకు ఒక గ్రాఫిక్స్ ఇంజిన్‌లో Shape అనే బేస్ క్లాస్ నుండి Circle, Rectangle, Triangle మొదలైన క్లాసులు ఉద్భవిస్తాయి. అవన్నీ షేప్ యొక్క కామన్ లక్షణాలైన రంగు, స్థానాన్ని వారసత్వంగా పొందుతాయి.

6 మల్టిపుల్ ఇన్హెరిటెన్స్ (Multiple Inheritance: బహుళ బేస్ క్లాసులు)

C++ ప్రోగ్రామింగ్ లాంగ్వేజ్ యొక్క అత్యంత విలక్షణమైన మరియు శక్తివంతమైన ఫీచర్లలో ఒకటి మల్టిపుల్ ఇన్హెరిటెన్స్.

ఒక చైల్డ్ క్లాస్ ఏకకాలంలో రెండు లేదా అంతకంటే ఎక్కువ స్వతంత్ర బేస్ క్లాసుల నుండి లక్షణాలను పొందడాన్ని మల్టిపుల్ ఇన్హెరిటెన్స్ అంటారు:

class SmartDevice : public Camera, public CellularPhone, public GPSNavigator {
    // మూడు విభిన్న డివైజ్‌ల శక్తులన్నీ ఇందులో ఉంటాయి!
};
multiple_inheritance_demo.cpp
#include <iostream>

class CameraModule {
public:
    void capturePhoto() {
        std::cout << "  📸 48MP హై-రిజల్యూషన్ ఫోటో తీయబడింది!\n";
    }
};

class CellularModem {
public:
    void makeCall(const std::string& number) {
        std::cout << "  📞 5G నెట్‌వర్క్ ద్వారా " << number << " కి కాల్ కనెక్ట్ అవుతోంది...\n";
    }
};

// రెండు స్వతంత్ర క్లాసుల నుండి మల్టిపుల్ ఇన్హెరిటెన్స్
class ModernSmartphone : public CameraModule, public CellularModem {
public:
    void browseWeb() {
        std::cout << "  🌐 బ్రౌజర్‌లో ఇంటర్నెట్ లోడ్ అవుతోంది...\n";
    }
};

int main() {
    ModernSmartphone phone;
    std::cout << "===== C++ మల్టిపుల్ ఇన్హెరిటెన్స్ డెమో =====\n";
    phone.capturePhoto();
    phone.makeCall("+91-9876543210");
    phone.browseWeb();
    return 0;
}

7 ది ఫేమస్ "Diamond Problem" (డైమండ్ అంబిగ్యుటీ విపత్తు)

మల్టిపుల్ ఇన్హెరిటెన్స్ చాలా శక్తివంతమైనదే అయినప్పటికీ, అది సాఫ్ట్‌వేర్ ఇంజనీరింగ్‌లో అత్యంత ప్రమాదకరమైన ఒక బగ్‌కు కారణమవుతుంది. దాని పేరే The Deadly Diamond Problem (డైమండ్ అంబిగ్యుటీ విపత్తు).

[The Classic Diamond Inheritance Diagram]
        [Class PoweredDevice] (Apex Base: int powerRating)
              /            \
             /              \
   [Class Scanner]         [Class Printer]
             \              /
              \            /
          [Class CopierMachine] (Derived from both)

విపత్తు: CopierMachine ఆబ్జెక్ట్ లోపల PoweredDevice యొక్క TWO కాపీలు పుడతాయి!
copier.powerRating అని పిలిస్తే -> కంపైలర్ ERROR: Request for member 'powerRating' is ambiguous!

పై చిత్రంలో CopierMachine ఆబ్జెక్ట్ సృష్టించబడినప్పుడు, Scanner ద్వారా ఒక powerRating కాపీ, Printer ద్వారా రెండవ powerRating కాపీ వస్తాయి. ఇప్పుడు ప్రోగ్రామర్ copier.powerRating = 200; అని రాస్తే, కంపైలర్ ఏ కాపీని మార్చాలో తెలియక గందరగోళానికి గురై ఎర్రర్ విసురుతుంది!

8 డైమండ్ ప్రాబ్లమ్‌కు శాశ్వత పరిష్కారం: virtual Base Classes

ఈ డైమండ్ విపత్తును సమూలంగా పరిష్కరించడానికి C++ మనకు అందించిన దివ్యౌషధమే virtual Base Classes!

మధ్యలో ఉన్న క్లాసులు బేస్ క్లాస్‌ను ఇన్హెరిట్ చేసుకునే సమయంలో virtual కీవర్డ్‌ను జోడించాలి:

class Scanner : virtual public PoweredDevice { ... };
class Printer : virtual public PoweredDevice { ... };

వర్చువల్ ఇన్హెరిటెన్స్ ఎలా పనిచేస్తుంది?

  • కంపైలర్ CopierMachine ఆబ్జెక్ట్ లోపల PoweredDevice యొక్క రెండు వేర్వేరు కాపీలను సృష్టించకుండా, కేవలం ఒకే ఒక్క ఉమ్మడి కాపీని (Single Shared Instance) మాత్రమే ఉంచుతుంది!
  • అంతర్గతంగా ప్రతి చైల్డ్ క్లాస్ ఒక Virtual Base Pointer (vbptr) ను మెమరీలో నిర్వహిస్తూ, ఆ షేర్డ్ బేస్ సబ్‌ఆబ్జెక్ట్‌ను చూపిస్తుంది.
  • దీనివల్ల అంబిగ్యుటీ పూర్తిగా తొలగిపోయి మెమరీ ఆదా అవుతుంది!
virtual_base_class_solution.cpp
#include <iostream>

class PoweredDevice {
public:
    int voltage;
    PoweredDevice(int v) : voltage(v) {
        std::cout << "  ⚡ [PoweredDevice] వోల్టేజ్ ఇనిషియలైజ్ చేయబడింది: " << voltage << "V\n";
    }
};

// 💡 వర్చువల్ ఇన్హెరిటెన్స్ ద్వారా డైమండ్ ప్రాబ్లమ్ పరిష్కారం!
class Scanner : virtual public PoweredDevice {
public:
    Scanner(int v) : PoweredDevice(v) {
        std::cout << "  📠 Scanner మాడ్యూల్ రెడీ.\n";
    }
};

class Printer : virtual public PoweredDevice {
public:
    Printer(int v) : PoweredDevice(v) {
        std::cout << "  🖨️ Printer మాడ్యూల్ రెడీ.\n";
    }
};

class CopierMachine : public Scanner, public Printer {
public:
    // వర్చువల్ బేస్ క్లాస్ ఉన్నప్పుడు, మోస్ట్ డిరైవ్డ్ క్లాస్ నేరుగా అపెక్స్ బేస్‌ను పిలవాలి!
    CopierMachine(int v) : PoweredDevice(v), Scanner(v), Printer(v) {
        std::cout << "  🏢 CopierMachine పూర్తిగా ఆపరేషనల్!\n";
    }
};

int main() {
    std::cout << "===== Virtual Base Class డైమండ్ పరిష్కార పరీక్ష =====\n";
    CopierMachine copier(240);

    // అంబిగ్యుటీ లేకుండా నేరుగా voltage ను యాక్సెస్ చేయవచ్చు!
    std::cout << "\nకాపియర్ వోల్టేజ్: " << copier.voltage << "V (ఏకైక షేర్డ్ ఇన్స్టాన్స్!)\n";
    return 0;
}

9 Constructor & Destructor Chaining (ఎగ్జిక్యూషన్ ఆర్డర్)

ఒక డిరైవ్డ్ క్లాస్ ఆబ్జెక్ట్ సృష్టించబడినప్పుడు మరియు నశించినప్పుడు వాటి కన్‌స్ట్రక్టర్లు మరియు డిస్ట్రక్టర్లు ఏ క్రమంలో ఎగ్జిక్యూట్ అవుతాయి?

  1. కన్‌స్ట్రక్టర్ల క్రమం (Top-to-Bottom / Base-to-Derived):
    ఒక ఇంటిని నిర్మించేటప్పుడు ముందుగా పునాది వేసి, ఆ తర్వాతే మొదటి అంతస్తు, రెండో అంతస్తు కడతారు కదా! అలాగే C++ లో ముందుగా Base Class Constructor అమలవుతుంది, ఆ తర్వాతే Derived Class Constructor అమలవుతుంది.
  2. డిస్ట్రక్టర్ల క్రమం (Bottom-to-Top / Derived-to-Base):
    ఒక ఇంటిని కూల్చేటప్పుడు పైకప్పు నుండి మొదలుపెట్టి చివరిగా పునాదిని తీసేస్తారు. సరిగ్గా అలాగే ముందుగా Derived Class Destructor అమలవుతుంది, చివరగా Base Class Destructor అమలవుతుంది (ఖచ్చితమైన రివర్స్ LIFO క్రమం!).
chaining_order_demo.cpp
#include <iostream>

class Parent {
public:
    Parent() { std::cout << "  1. [Parent Constructor] పునాది వేయబడింది.\n"; }
    ~Parent() { std::cout << "  4. [Parent Destructor] పునాది తొలగించబడింది.\n"; }
};

class Child : public Parent {
public:
    Child() { std::cout << "  2. [Child Constructor] భవనం నిర్మించబడింది.\n"; }
    ~Child() { std::cout << "  3. [Child Destructor] భవనం కూల్చబడింది.\n"; }
};

int main() {
    std::cout << "స్కోప్ ప్రారంభం...\n";
    {
        Child c;
    } // ఇక్కడ స్కోప్ ముగిసింది
    std::cout << "స్కోప్ ముగిసింది.\n";
    return 0;
}

10 మెథడ్ ఓవర్‌రైడింగ్ & C++ Name Hiding Trap

ఒక బేస్ క్లాస్ లో ఉన్న ఫంక్షన్‌కు భిన్నమైన కొత్త ప్రవర్తనను చైల్డ్ క్లాస్‌లో ఇవ్వడాన్నే మెథడ్ ఓవర్‌రైడింగ్ (Method Overriding) అంటారు.

⚠️ The Dreaded Name Hiding Trap:
C++ లో ఒక బేస్ క్లాస్‌లో void show(int) మరియు void show(double) ఓవర్‌లోడ్స్ ఉన్నాయనుకుందాం. ఇప్పుడు మీరు చైల్డ్ క్లాస్‌లో కేవలం void show(string) అని రాస్తే, బేస్ లోని show(int) మరియు show(double) రెండూ పూర్తిగా దాగిపోతాయి (Hidden)! చైల్డ్ ఆబ్జెక్ట్‌తో c.show(5) అని పిలిస్తే కంపైలర్ ఎర్రర్ వస్తుంది.
పరిష్కారం: చైల్డ్ క్లాస్ లోపల using Base::show; అని స్పష్టంగా చెప్పడం ద్వారా బేస్ ఓవర్‌లోడ్స్‌ను తిరిగి బహిర్గతం చేయవచ్చు!

11 Composition vs Inheritance: "Prefer Composition over Inheritance"

సాఫ్ట్‌వేర్ ఆర్కిటెక్చర్‌లో ప్రముఖ డిజైన్ సూత్రం: "Favor Object Composition over Class Inheritance".

  • Inheritance (Is-A): చైల్డ్ క్లాస్ బేస్ క్లాస్‌తో గట్టిగా ముడిపడి ఉంటుంది (Tight Coupling). బేస్ క్లాస్‌లో చిన్న మార్పు జరిగినా అన్ని చైల్డ్ క్లాసులు ప్రభావితమవుతాయి.
  • Composition (Has-A): ఒక క్లాస్ లోపల మరొక క్లాస్ ఆబ్జెక్ట్‌ను ఒక వేరియబుల్ గా ఉంచుకోవడం (Loose Coupling). ఉదాహరణకు ఒక కారుకు ఇంజిన్ ఉంటుంది (Car HAS-A Engine). కారు అనేది ఇంజిన్ కాదు! కాబట్టి class Car : public Engine అని రాయకూడదు; బదులుగా class Car { Engine engine; }; అని రాయాలి.

12 రియల్-వరల్డ్ ప్రాజెక్ట్: Enterprise Defense Autonomous Combat Drone Fleet Engine

రక్షణ మరియు ఏరోస్పేస్ రంగంలో ఉపయోగించే ఆధునిక సైనిక మానవరహిత యుద్ధ డ్రోన్లు (Autonomous Stealth UCAVs - Unmanned Combat Aerial Vehicles) అత్యంత సంక్లిష్టమైన హార్డ్‌వేర్ ఆర్కిటెక్చర్‌ను కలిగి ఉంటాయి.

ఒక డ్రోన్ ప్రాథమికంగా ఒక ఏవియేషన్ ప్లాట్‌ఫామ్ (AvionicsPlatform); అదే సమయంలో అది ఒక స్టీల్త్ రాడార్ సర్వైలెన్స్ యూనిట్ (StealthSurveillanceUnit) మరియు ఒక ప్రెసిషన్ వెపన్ కంట్రోలర్ (PrecisionWeaponController). ఇవి రెండూ ఉమ్మడి ఏవియేషన్ పవర్ సిస్టమ్‌ను పంచుకోవాలి (వర్చువల్ బేస్ క్లాస్ ద్వారా డైమండ్ ప్రాబ్లం పరిష్కారం).

ఈ సమగ్ర ప్రాజెక్ట్‌లో మనం వర్చువల్ ఇన్హెరిటెన్స్, మల్టిపుల్ ఇన్హెరిటెన్స్ మరియు కన్‌స్ట్రక్టర్ చైనింగ్‌తో కూడిన ఎంటర్‌ప్రైజ్ కాంబ్యాట్ డ్రోన్ మిషన్ ఇంజిన్ ను నిర్మిస్తున్నాం:

CombatDroneFleetEngine.cpp
#include <iostream>
#include <string>
#include <iomanip>

// అపెక్స్ బేస్ క్లాస్: ఏవియోనిక్స్ పవర్ & టెలిమెట్రీ
class AvionicsCore {
protected:
    std::string droneSerial;
    double currentBatteryKWh;
    double altitudeMeters;

public:
    AvionicsCore(std::string serial, double battery)
        : droneSerial(serial), currentBatteryKWh(battery), altitudeMeters(0.0) {
        std::cout << "  🚁 [AvionicsCore Base] పవర్ బస్ ఆన్ చేయబడింది: " << droneSerial 
                  << " (బ్యాటరీ: " << currentBatteryKWh << " kWh)\n";
    }

    virtual ~AvionicsCore() {
        std::cout << "  🛑 [AvionicsCore Base] ఏవియోనిక్స్ పవర్ సురక్షితంగా షట్‌డౌన్ చేయబడింది.\n";
    }

    void climb(double meters) {
        altitudeMeters += meters;
        currentBatteryKWh -= (meters * 0.001);
        std::cout << "  ✈️ [ఎత్తు పెంపు] ఎత్తు: " << altitudeMeters << " మీటర్లు | మిగిలిన పవర్: " << currentBatteryKWh << " kWh\n";
    }
};

// బ్రాంచ్ 1: వర్చువల్ బేస్ ఇన్హెరిటెన్స్ (డైమండ్ నివారణ)
class SurveillanceRadar : virtual public AvionicsCore {
protected:
    double radarScanRangeKm;

public:
    SurveillanceRadar(std::string serial, double battery, double scanRange)
        : AvionicsCore(serial, battery), radarScanRangeKm(scanRange) {
        std::cout << "  📡 [SurveillanceRadar] AESA రాడార్ యాక్టివేట్ చేయబడింది (పరిధి: " << radarScanRangeKm << " KM)\n";
    }

    void scanForHostiles() {
        std::cout << "  🔍 [రాడార్ స్కానింగ్] " << radarScanRangeKm << " KM పరిధిలో గగనతల శత్రు లక్ష్యాల అన్వేషణ జరుగుతోంది...\n";
    }
};

// బ్రాంచ్ 2: వర్చువల్ బేస్ ఇన్హెరిటెన్స్ (డైమండ్ నివారణ)
class PrecisionWeaponBay : virtual public AvionicsCore {
protected:
    int payloadMissiles;

public:
    PrecisionWeaponBay(std::string serial, double battery, int missiles)
        : AvionicsCore(serial, battery), payloadMissiles(missiles) {
        std::cout << "  🎯 [PrecisionWeaponBay] గైడెడ్ క్షిపణి లాంచర్ లోడ్ చేయబడింది (మిస్సైల్స్: " << payloadMissiles << ")\n";
    }

    void fireMissile(const std::string& targetCoordinates) {
        if (payloadMissiles > 0) {
            payloadMissiles--;
            std::cout << "  🚀 [మిస్సైల్ ప్రయోగం!] టార్గెట్ కోఆర్డినేట్స్: " << targetCoordinates 
                      << " పైకి క్షిపణి దూసుకెళ్లింది! (మిగిలినవి: " << payloadMissiles << ")\n";
        } else {
            std::cout << "  ⚠️ హెచ్చరిక: క్షిపణులు అయిపోయాయి! వెంటనే బేస్ కు తిరిగి రండి.\n";
        }
    }
};

// డైమండ్ చైల్డ్: మల్టిపుల్ ఇన్హెరిటెన్స్ ఫ్రమ్ SurveillanceRadar & PrecisionWeaponBay
class CombatStealthUAV : public SurveillanceRadar, public PrecisionWeaponBay {
private:
    std::string callSign;

public:
    // మోస్ట్ డిరైవ్డ్ క్లాస్ నేరుగా వర్చువల్ అపెక్స్ బేస్ (AvionicsCore) ను ఇనిషియలైజ్ చేయాలి!
    CombatStealthUAV(std::string serial, std::string callName, double battery, double scanRange, int missiles)
        : AvionicsCore(serial, battery),
          SurveillanceRadar(serial, battery, scanRange),
          PrecisionWeaponBay(serial, battery, missiles),
          callSign(callName) {
        std::cout << "\n  ⚡ [COMBAT STEALTH UAV READY] కాల్‌సైన్: " << callSign << " పోరాటానికి సిద్ధం!\n";
    }

    void executeCombatMission(const std::string& targetGrid) {
        std::cout << "\n==============================================================\n";
        std::cout << "⚔️ [మిషన్ ఎగ్జిక్యూషన్ - " << callSign << " / " << droneSerial << "]\n";
        std::cout << "==============================================================\n";
        climb(12000.0); // 12 కిమీ ఎత్తుకు ఎగరడం
        scanForHostiles();
        fireMissile(targetGrid);
        std::cout << "లక్ష్యం ధ్వంసమైంది! బేస్ కు తిరుగు ప్రయాణం ప్రారంభం...\n";
        std::cout << "==============================================================\n";
    }
};

int main() {
    std::cout << "==============================================================\n";
    std::cout << "🛡️ [DEFENSE AEROSPACE COMBAT DRONE SIMULATION RUNNING]\n";
    std::cout << "==============================================================\n";

    {
        // డ్రోన్ సృష్టి (సింగిల్ షేర్డ్ ఏవియోనిక్స్ పవర్ కోర్ తో!)
        CombatStealthUAV droneX("DRONE_IAF_GHAATAK_01", "GARUDA_STRIKE", 250.0, 150.0, 4);

        // మిషన్ అమలు
        droneX.executeCombatMission("SECTOR_4_ENEMY_RADAR_BUNKER_34.5N_72.8E");
    } // స్కోప్ ముగియగానే రివర్స్ ఆర్డర్‌లో అన్నీ లీక్-ఫ్రీగా క్లీన్ అవుతాయి!

    std::cout << "\nమిషన్ ముగింపు. వర్చువల్ ఇన్హెరిటెన్స్ ఆర్కిటెక్చర్ విజయవంతమైంది!\n";
    return 0;
}

13 సారాంశం & ఇంటరాక్టివ్ క్విజ్ (Summary & Self-Check Quizzes)

📌 ఈ అధ్యాయంలో నేర్చుకున్న ప్రధాన అంశాలు:

  • Inheritance Concept: కోడ్ పునర్వినియోగం మరియు "Is-A" సంబంధాల రూపకల్పనకు మూలస్తంభం.
  • Access Modes: public, protected, private ఇన్హెరిటెన్స్ ద్వారా బేస్ మెంబర్ల దృశ్యమానతను నియంత్రించడం. వాస్తవ ప్రాజెక్టులలో పబ్లిక్ ఇన్హెరిటెన్స్ ప్రామాణికం.
  • Multiple Inheritance: ఒక చైల్డ్ క్లాస్ బహుళ స్వతంత్ర బేస్ క్లాసుల నుండి లక్షణాలను వారసత్వంగా పొందడం.
  • The Diamond Problem: రెండు వేర్వేరు మార్గాల్లో ఒకే బేస్ క్లాస్ నుండి మల్టిపుల్ ఇన్హెరిటెన్స్ జరిగినప్పుడు డేటా డూప్లికేషన్ మరియు అంబిగ్యుటీ రావడం.
  • Virtual Base Classes: virtual public Base ద్వారా కంపైలర్ కేవలం ఒకే ఒక్క సింగిల్ షేర్డ్ కాపీని ఉంచేలా చేసి డైమండ్ సమస్యను శాశ్వతంగా పరిష్కరించడం.
  • Chaining Order: కన్‌స్ట్రక్టర్లు బేస్ నుండి చైల్డ్‌కు (Top-to-Bottom) మరియు డిస్ట్రక్టర్లు చైల్డ్ నుండి బేస్‌కు (Bottom-to-Top) అమలవుతాయి.
  • Composition over Inheritance: గట్టి బంధం (Tight Coupling) నివారించడానికి "Is-A" లేని చోట ఆబ్జెక్ట్ కంపోజిషన్ (Has-A) ను ఎంచుకోవాలి.

🧠 మీ అవగాహనను పరీక్షించుకోండి (5 Interactive Quizzes):

ప్రశ్న 1: C++ లో ఒక బేస్ క్లాస్‌లోని protected మెంబర్లకు మరియు private మెంబర్లకు ఉన్న కీలక వ్యత్యాసం ఏమిటి?
సమాధానం: protected మెంబర్లను డిరైవ్డ్ (చైల్డ్) క్లాసులు నేరుగా యాక్సెస్ చేయగలవు, కానీ private మెంబర్లను చైల్డ్ క్లాసులు కూడా తాకలేవు!
వివరణ: private అనేది కేవలం ఆ నిర్దిష్ట క్లాస్‌కు మాత్రమే పరిమితం. protected అనేది బాహ్య ప్రపంచానికి ప్రైవేట్‌గా ఉంటూనే, వారసత్వంగా వచ్చే పిల్ల క్లాసులకు మాత్రమే స్వేచ్ఛాయుత యాక్సెస్‌ను ఇస్తుంది.
ప్రశ్న 2: The Diamond Problem లో కంపైలర్ ఎర్రర్ రావడానికి అసలు కారణం ఏమిటి?
సమాధానం: ఆబ్జెక్ట్ లోపల అపెక్స్ బేస్ క్లాస్ యొక్క రెండు వేర్వేరు డూప్లికేట్ కాపీలు ఏర్పడి అంబిగ్యుటీ (Member Ambiguity) రావడం వల్ల!
వివరణ: క్లాస్ D అనేది B మరియు C రెండింటి నుండీ A ని పొందినప్పుడు, A లోని వేరియబుల్స్ రెండుసార్లు మెమరీలో పుడతాయి. d.variable అన్నప్పుడు ఏ కాపీని వాడాలో కంపైలర్ తేల్చుకోలేక ఎర్రర్ విసురుతుంది.
ప్రశ్న 3: డైమండ్ సమస్యను పరిష్కరించడానికి virtual బేస్ క్లాస్ వాడినప్పుడు అంతర్గతంగా ఏం జరుగుతుంది?
సమాధానం: కంపైలర్ కేవలం ఒకే ఒక్క సింగిల్ షేర్డ్ బేస్ సబ్‌ఆబ్జెక్ట్‌ను ఉంచి, పాయింటర్ల (vbptr) ద్వారా కలుపుతుంది!
వివరణ: virtual కీవర్డ్ ఉండటం వల్ల కంపైలర్ డూప్లికేట్ కాపీలను సృష్టించదు. అన్ని ఇంటర్మీడియట్ క్లాసులు ఒకే పంచుకున్న బేస్ ఇన్స్టాన్స్‌ను రిఫర్ చేస్తాయి, ఫలితంగా అంబిగ్యుటీ మాయమవుతుంది.
ప్రశ్న 4: ఒక చైల్డ్ క్లాస్ ఆబ్జెక్ట్ సృష్టించబడినప్పుడు కన్‌స్ట్రక్టర్ల మరియు డిస్ట్రక్టర్ల అమలు క్రమం (Execution Order) ఎలా ఉంటుంది?
సమాధానం: కన్‌స్ట్రక్టర్లు Base -> Derived క్రమంలో, డిస్ట్రక్టర్లు Derived -> Base క్రమంలో అమలవుతాయి!
వివరణ: పునాది పడిన తర్వాతే భవనం ఏర్పడుతుంది, కాబట్టి ముందు బేస్ కన్‌స్ట్రక్టర్ రన్ అవుతుంది. కూల్చేటప్పుడు రివర్స్ ఆర్డర్‌లో ముందు చైల్డ్ డిస్ట్రక్ట్ అయ్యి, ఆ తర్వాత బేస్ క్లీన్ అవుతుంది.
ప్రశ్న 5: "Car" మరియు "Engine" మధ్య ఏ రకమైన సంబంధం సరైనది? (Is-A లేక Has-A?)
సమాధానం: Has-A (Composition) మాత్రమే సరైనది!
వివరణ: ఒక కారుకు ఇంజిన్ ఉంటుంది (Car HAS-AN Engine), కానీ కారు అనేది ఒక ఇంజిన్ కాదు (Car IS NOT an Engine). కాబట్టి ఇక్కడ ఇన్హెరిటెన్స్ వాడటం డిజైన్ పరంగా తీవ్రమైన తప్పు; కారు క్లాస్ లోపల ఇంజిన్ ఆబ్జెక్ట్‌ను ఒక వేరియబుల్‌గా ఉంచడం (Composition) సరైన పద్ధతి.
← మునుపటి అధ్యాయం: 14. Constructors & Destructors తర్వాతి అధ్యాయం: 16. పాలిమార్ఫిజమ్ →

ఈ ప్రాజెక్ట్‌ను లైవ్‌గా మన కంపైలర్‌లో రన్ చేయండి!

ఎటువంటి లోకల్ సెటప్ లేకుండా, బ్రౌజర్‌లోనే నేరుగా Modern C++ (GCC 13 / C++20) కంపైలర్‌లో ఈ కోడ్‌ను ఎగ్జిక్యూట్ చేసి రన్‌టైమ్ అవుట్‌పుట్‌ను తనిఖీ చేయండి.