Search code examples
c++classfriend

Why can't this friend function access the private variables?


class Student{
public:
Student(int test)
:key(705)
{
    if(test == key)
    {cout << "A student is being verified with a correct key: "<< test << endl;
    allow=1;
    }
    else
    {
        cout << "Wrong key" ;
    }
}

friend void printResult();


private:
const int key;
int allow;


};

void printResult()
{
 if(allow==1)
 {
   cout<< " Maths: 75 \n Science:80 \n English: 75" << endl;
  }
}

int main()
{
int testkey;
cout << "Enter key for Bob: ";
cin >> testkey;

Student bob(testkey);

printResult();

}

The function printResult can't seem to access the variable allow, which is private, from the Student class. Did I prototype the printResult in the wrong place or was the syntax wrong? AFAIK, we can prototype friends anywhere in the class.


Solution

  • Here is some code that works:

    #include <iostream>
    class Student
    {
    public:
    Student(int test) : key(705)
    {
        if(test == key)
        {
            std::cout << "A student is being verified with a correct key: "<< test <<    std::endl;
            allow=1;
        }
        else
        {
            std::cout << "Wrong key" ;
        }
    }
    
    friend void printResult(Student* student);
    
    private:
        const int key;
        int allow;
    };
    
    void printResult(Student* student)
    {
        if(student->allow==1)
        {
            std::cout<< " Maths: 75 \n Science:80 \n English: 75" << std::endl;
        }
    }
    
    int main(int argc, char* argv[])
    {
        int testkey;
        std::cout << "Enter key for Bob: ";
        std::cin >> testkey;
    
        Student bob(testkey);
    
        printResult(&bob);
    }
    

    I modified it to keep the print function in the global space (just based on what it looked like you wanted). It takes a Student* argument and because it is declared as a friend it will see the "allow" variable. This however is not a part of C++ you will want to abuse. Be careful with how you use friend. Using it like this is dangerous in a bigger code base. Global functionality is usually not the way to go. Having the print function as a public member function within the student class would probably be a better way to do things. Other answers have provided code that shows that implementation. I decided to show you this implementation as it seemed more close to what you were looking for in your question.

    I also make sure to use 'std::' when referring to cout and endl. This removes the need to have 'using namespace std;' at the top. This is just good programming practice down the road in more complicated projects.