Search code examples
c++friend

Friend function cannot access private data member (c++)


I have searched many different questions and could not find a solution that matched my specific problem. I have this header file for a queue:

#ifndef HEADERFILE
#define HEADERFILE
#include <iostream>
#include <vector>
using namespace std;

template<class myType>
class Queue{
  private:

    int size;
    vector<myType> list; 

  public:

    Queue(int);
    void Enqueue(myType);
    myType Dequeue();
    myType PeekFront();
    int length();
    void empty();
    myType Index(int);
    friend void printArray();

};

#endif

The issue in question is for friend void printArray. Here is the implementation file:

#include "queueTask1.h"
#include <vector>
#include <iostream>

using namespace std;

(Other function implementations)

void printArray(){
    for (int i = 0; i < list.size(); i++){
        cout << list.at(i) << ", ";
    }
    cout << endl;
}

The error when attempting to run this states that

'list' is not declared in this scope

however it is declared in the header file and all other member functions work fine. For some reason printArray cannot find the private data member list, even though it should be a friend function.


Solution

  • list is a non static data member. That means there is one list for each object. Since it is object dependent you need an object to access its list. The simplest way to do that is to pass the object to the function like

    // forward declare the function, unless you want to define the function inside the class
    template<class ElementType>
    friend void printArray(const Queue<ElementType>&);
    
    template<class myType>
    class Queue{
        //...
        // declare the friendship
        template<class ElementType>
        friend void printArray(const Queue<ElementType>&);
        //...
    };
    
    // define the function
    template<class ElementType>
    void printArray(const Queue<ElementType>& q)
    {
        for (int i = 0; i < q.list.size(); i++){
            cout << q.list.at(i) << ", ";
        }
        cout << endl;
    }   
    

    You also need to move your implementation of Queue into the header file since it is a temaplte. For more one this see: Why can templates only be implemented in the header file?