user2477112
user2477112

Reputation: 63

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.

Upvotes: 4

Views: 6766

Answers (5)

Dean Knight
Dean Knight

Reputation: 680

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.

Upvotes: 2

TelKitty
TelKitty

Reputation: 3156

class Student{    
private:
const int key;
int allow;    
public:
Student(int test)
:key(705)
{
    if(test == key)
    {cout << "A student is being verified with a correct key: "<< test << endl;
    int allow=1;
    }
    else
    {
        cout << "Wrong key" ;
    }
}    
friend void printResult(); 
void printResult() //<---  printResult() is a member function, so keep it inside the class
{
 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);   
bob.printResult(); // <--- you need to specify the owner of printResult()   
}

Upvotes: 2

user123
user123

Reputation: 9071

That's because allow belongs to an instance of the class, but no instance is being referred to.

You should probably make printResult a member function of the class instead of making it an external function or make the function take a reference to a Student instance so you can access the allow member via the instance.allow where instance is a parameter of type const Student&.

Upvotes: 5

Marius
Marius

Reputation: 837

Class friend function are allowed to access members of a class instance. You should pass the instance to the function, like:

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

Upvotes: 1

juanchopanza
juanchopanza

Reputation: 227400

printResult is not a member function, so you need to give it a Student instance to act on. For example

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

then

Student student(1);
printResult(student);

Upvotes: 5

Related Questions