MeIsNoob
MeIsNoob

Reputation: 69

C++ Friend method cannot access private data from class

I am doing my project which is simulation of school system.
I have problem with the fact that a method from class Klasa (Polish for class) cannot access private data from class Student, even though I declared this method as a friend in Student.

Here is the code:

First Student.h:

#include <iostream>
#include "Klasa.h"
#include "SubjectType.h"
#include "SubjectGrades.h"
using namespace std;
    class Klasa;
    class SubjectGrades;

    class Student
    {
    private:
        char* name;
        int id;


        Klasa* myClass;
        //School* mySchool;
        int classIndex; //numer w dzienniku - zrobić prywatne z akcesorami
        static int counter;
    public:



        Student();
        Student(char*);
        Student(const Student&);
        Student& operator= (const Student&);
        ~Student();

        //bool assignToSchool(School*)
        //bool resignFromSchool();
        void assignToClass(Klasa*);
        void resignFromClass();
        double getMyAverageGrade(SubjectType type) const ;      //srednia ocen z danego przedmiotu dla danego ucznia
        double getMyAverageGrade() const;       //średnia ocen dla danego ucznia

        bool operator== (const Student&);
        bool operator!= (const Student&);
        friend ostream& operator<< (ostream&, const Student&);
        // akcesory
        int GetclassIndex() const;
        int SetclassIndex(int i);
        friend bool Klasa::assignToKlasa(Student* s);
        char* GetName() const { return name; }
    };

Now method from class Klasa:

    bool Klasa::assignToKlasa(Student* s)
    {
        if(studentCount < maxStudentCount)
        {
            if(containsStudent(s))
                return false;

            if(studentCount < klasaSize) //jest miejsce dla studenta
            {
                int i = 0;
                while(studentList[i] != NULL)
                    i++;
                studentList[i] = s;

                s->classIndex=i;// = i; //tu musi byc setter
            }
            //WHATS BELOW DOESN'T MATTER FOR THIS PROBLEM, SO U DON;T NEED TO READ.


            else
            {
                cout << "Zwiekszamy rozmiar!\n";
                //musimy zwiększyć rozmiar tablicy studentList
                Student** newStudentList = new Student*[klasaSize + sizeStep];
                for(int i = 0; i < klasaSize; ++i)
                    newStudentList[i] = studentList[i];

                for(int i = klasaSize; i < klasaSize + sizeStep; ++i)
                    newStudentList[i] = NULL;

                klasaSize += sizeStep;

                delete[] studentList;
                studentList = newStudentList;

                studentList[studentCount] = s;

                s->SetclassIndex(studentCount); //tu ma byc setter

            }

            s->assignToClass(this); //mówimy studentowi - "jestem twoją klasą"
            studentCount++;
            cout << "Dodano studenta!\n";

            return true;
        }

        return false;
    }

It underlines s->classIndex=i that classIndex cannot be accessed.

Also in Klasa.h I declared this method like: bool assignToKlasa(Student* s);

So I have no idea why it doesn't let me access private data from student after I declared it in student as a friend? Could you please help me?

Upvotes: 2

Views: 4473

Answers (2)

Walter
Walter

Reputation: 45424

For this equivalent code

class A;
class B {
  int x;
public:
  B(int __x) : x(__x) {}
  friend bool A::method(B*) const;   // error: undefined member cannot be friend
//friend class A;                    // fine:  class A is declared and can be used
};

class A {
  int y;
pu8blic:
  A(int __y) : y(__y) {}
  bool method(B*b) const
  { return y == b->x; }
};

I get the error messages (with gcc 4.3.2):

test3.cc:7: error: invalid use of incomplete type ‘struct A’

test3.cc:1: error: forward declaration of ‘struct A’

test3.cc: In member function ‘bool A::method(B*) const’:

test3.cc:3: error: ‘int B::x’ is private

test3.cc:15: error: within this context

The first error is the only one you have to worry about (the others are either explanations or consequences of the first). So how can one sort this out? One simple way to fix the problem is to declare the whole class A to be friend of B by replacing

  friend bool A::method(B*) const;

with

  friend class A;

which is defined.

Upvotes: 1

Steve Jessop
Steve Jessop

Reputation: 279255

Your definition of class Student { ... } shouldn't compile either. The friend declaration is an error, so I'm surprised that isn't highlighted too. What your IDE has figured out is that the access to a private member isn't allowed without a working friend declaration.

The error is that a forward declaration of Klasa is not enough to declare a member function of Klasa to be a friend of Student. You need the class definition of Klasa first.

So, it should be:

class Student; // forward declaration, because members of Klasa take Student*

class Klasa { 
    ... 
};

class Student { 
    ... 
};

then you can define Klasa::assignToKlasa.

Upvotes: 4

Related Questions