Search code examples
c++functionclassmemberfriend

How to grant friend class access to value of modified member


What is the proper method to grant class access to modified value of private member of different class.

Using Friend Class is granting me access to value of private member if provided but won't let me access to modified value data of that member.

For example when I am building vector in one Class and I would like to work on build up data of that vector in another class.

How to grant access for

bar_start.Print()

have the same values as

foo_start.PrintData()

I believe its still in memory and it wasn't deleted

class Foo
{
public:
    Foo();
    ~Foo();
    void ChangeData();
    void PrintData();

private:
    int k = 0;
    std::vector<int> m_vector;
    friend class Bar;
};

class Bar
{
public:
    Bar();
    ~Bar();
    void Print();
};

void Foo::ChangeData()
{
    m_vector.push_back(1);
    int k = 5;
}

void Foo::PrintData()
{
    std::cout << k << std::endl;
    std::cout << m_vector[0] << std::endl;
}

void Bar::Print()
{
    Foo obj;
    std::cout << obj.k << std::endl;
    std::cout << obj.m_vector[0] << std::endl;
}

// printing in main() function

Foo foo_start;
Bar bar_start;

foo_start.ChangeData();
foo_start.PrintData(); // k = 5, m_vector[0] = 1;

bar_start.Print(); // k = 0, m_vector[0] empty and error due not existing element in vector

Solution

  • You may want to store a reference / pointer to a particular Foo inside each Bar instance.

    class Bar {
    public:
        Bar(Foo& f) : foo(&f) {} // take a Foo by reference and store a pointer to it
    
        void Print();
    
    private:
        Foo* foo;
    };
    
    void Bar::Print() { // use the pointer to the Foo in here:
        std::cout << foo->k << std::endl;
        std::cout << foo->m_vector[0] << std::endl;
    }
    

    You would then need to create each Bar supplying the Foo instance you'd like it to be connected to so to speak:

    int main() {
        Foo foo_start;
        Bar bar_start(foo_start); // this Bar now stores a pointer to foo_start
    
        foo_start.ChangeData();
        bar_start.Print();
    }
    

    Also note that the k you instantiate inside ChangeData is not the member variable k. You initialize a new variable named k with 5 and then that k is forgotten.

    void Foo::ChangeData()
    {
        m_vector.push_back(1);
        int k = 5;
    }
    

    If you want to make a change to the member variable k, remove the declaration part and just assign 5 to it:

    void Foo::ChangeData()
    {
        m_vector.push_back(1);
        k = 5;
    }