#include <iostream>
using namespace std;

// Forward declare friend class
class FriendClass;

// Base class: demonstrating three access levels
class Base {
private:
    int privateVar;      // Only accessible within class and by friends
protected:
    int protectedVar;    // Accessible within class, derived classes, and by friends
public:
    int publicVar;       // Accessible anywhere

    // Constructor
    Base() : privateVar(1), protectedVar(2), publicVar(3) {
        cout << "Base construction completed" << endl;
    }

    // Regular member function: can access all members within class
    void showInside() {
        cout << "Base::showInside() -> "
             << "privateVar=" << privateVar
             << ", protectedVar=" << protectedVar
             << ", publicVar=" << publicVar << endl;
    }

private:
    void privateFunc() {
        cout << "Base::privateFunc() called" << endl;
    }
protected:
    void protectedFunc() {
        cout << "Base::protectedFunc() called" << endl;
    }
public:
    void publicFunc() {
        cout << "Base::publicFunc() called" << endl;
    }

    // Declare a global friend function
    friend void globalFriendFunc(Base& b);
    // Declare a friend class
    friend class FriendClass;
};

// Global friend function: can access all members of base class (including private and protected)
void globalFriendFunc(Base& b) {
    cout << "globalFriendFunc() accessing private member: " << b.privateVar << endl;
    cout << "globalFriendFunc() accessing protected member: " << b.protectedVar << endl;
    cout << "globalFriendFunc() accessing public member: " << b.publicVar << endl;
    b.privateFunc();   // Call private function
    b.protectedFunc(); // Call protected function
    b.publicFunc();    // Call public function
}

// Friend class: its member functions can access all members of base class
class FriendClass {
public:
    void accessBase(Base& b) {
        cout << "FriendClass::accessBase() accessing private member: " << b.privateVar << endl;
        cout << "FriendClass::accessBase() accessing protected member: " << b.protectedVar << endl;
        cout << "FriendClass::accessBase() accessing public member: " << b.publicVar << endl;
        b.privateFunc();
        b.protectedFunc();
        b.publicFunc();
    }
};

// Public inheritance derived class
class DerivedPublic : public Base {
private:
    int derivedPrivate;
protected:
    int derivedProtected;
public:
    int derivedPublic;

    DerivedPublic() : derivedPrivate(10), derivedProtected(20), derivedPublic(30) {}

    // Derived class member function: can access base class public and protected members, but cannot access private members
    void accessBaseMembers() {
        // cout << privateVar;  // Error: base class private members cannot be directly accessed
        cout << "Derived class accessing base class protected member: " << protectedVar << endl;
        cout << "Derived class accessing base class public member: " << publicVar << endl;

        // protectedFunc();  // Can call protected member functions
        // publicFunc();     // Can call public member functions
        // privateFunc();    // Error: private member functions cannot be accessed
    }

    // Derived class's own display
    void showDerived() {
        cout << "DerivedPublic members: derivedPrivate(not accessible externally)=" << derivedPrivate
             << ", derivedProtected=" << derivedProtected
             << ", derivedPublic=" << derivedPublic << endl;
    }
};

// Private inheritance derived class (for demonstrating inheritance type effects)
class DerivedPrivate : private Base {
public:
    void accessBaseMembers() {
        // Inside derived class, base class public and protected members are still accessible
        cout << "DerivedPrivate::accessBaseMembers() -> base class protected member: " << protectedVar << endl;
        cout << "DerivedPrivate::accessBaseMembers() -> base class public member: " << publicVar << endl;
        // Private members still not accessible
    }
};

// External regular function (non-friend): can only access object's public members
void externalFunc(Base& b) {
    cout << "externalFunc() accessing public member: " << b.publicVar << endl;
    b.publicFunc();
    // cout << b.protectedVar; // Error: protected members cannot be accessed externally
    // cout << b.privateVar;   // Error: private members cannot be accessed externally
}

int main() {
    cout << "========== 1. Base Class Object Direct Access ==========" << endl;
    Base b;
    // Public members: can be directly accessed
    b.publicVar = 100;
    b.publicFunc();
    // Protected members: cannot be directly accessed outside class (uncommenting will cause compilation error)
    // b.protectedVar = 200;
    // b.protectedFunc();
    // Private members: cannot be directly accessed outside class
    // b.privateVar = 300;
    // b.privateFunc();

    cout << "\n========== 2. Base Class Internal Access ==========" << endl;
    b.showInside();  // Internal functions can access all members

    cout << "\n========== 3. Derived Class Object (Public Inheritance) Access ==========" << endl;
    DerivedPublic d;
    // Access base class members through derived class object: only base class public members can be accessed through object
    d.publicVar = 101;
    d.publicFunc();
    // d.protectedVar = 201;  // Error: base class protected members cannot be accessed outside derived class
    // d.protectedFunc();     // Error
    // d.privateVar = 301;    // Error
    // d.privateFunc();       // Error
    // But derived class's own members follow permission rules
    d.derivedPublic = 31;
    // d.derivedProtected = 21; // Error: derived class's own protected members cannot be accessed outside class
    // d.derivedPrivate = 11;   // Error: private members cannot be accessed outside class
    cout << "Derived class object accessing its own public member: " << d.derivedPublic << endl;
    d.showDerived();
    d.accessBaseMembers();  // Derived class internal access to base class protected/public members

    cout << "\n========== 4. Derived Class Member Function Internal Access ==========" << endl;
    // Already demonstrated in accessBaseMembers()

    cout << "\n========== 5. External Regular Function Access ==========" << endl;
    externalFunc(b);

    cout << "\n========== 6. Friend Function Access ==========" << endl;
    globalFriendFunc(b);

    cout << "\n========== 7. Friend Class Access ==========" << endl;
    FriendClass fc;
    fc.accessBase(b);

    cout << "\n========== 8. Effect of Private Inheritance ==========" << endl;
    DerivedPrivate dp;
    dp.accessBaseMembers();   // Internally can still access base class public and protected
    // dp.publicVar = 102;    // Error: due to private inheritance, base class public members become private in derived class externally
    // dp.publicFunc();       // Same error
    // Can indirectly access through public interface added by derived class (accessBaseMembers already does this)
    cout << "Private inheritance makes all base class members invisible externally (except through public interface provided by derived class)" << endl;

    cout << "\n========== Summary ==========" << endl;
    cout << "- public: Accessible inside and outside class, inside and outside derived class (direct object access)." << endl;
    cout << "- protected: Accessible inside class and derived class, not accessible outside class (except friends)." << endl;
    cout << "- private: Only accessible inside class (and friends), not accessible in derived class." << endl;
    cout << "- Friends break encapsulation and can access any member." << endl;
    cout << "- Different inheritance types change access levels of base class members in derived class." << endl;

    return 0;
}

results matching ""

    No results matching ""