【问题标题】:C++ Friend method cannot access private data from classC++ Friend 方法不能从类访问私有数据
【发布时间】:2012-06-13 17:22:04
【问题描述】:

我正在做一个模拟学校系统的项目。
我对来自 Klasa 类(类波兰语)的方法无法访问 Student 类的私有数据这一事实有疑问,即使我在 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; }
    };

来自 Klasa 类的 Now 方法:

    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;
    }

它强调s-&gt;classIndex=i classIndex 不能被访问。

我也在 Klasa.h 中声明了这个方法:bool assignToKlasa(Student* s);

所以我不知道为什么在我将学生声明为朋友之后,它不允许我访问学生的私人数据?你能帮帮我吗?

【问题讨论】:

  • 您到底在哪里定义 Klasa 是 Student 的朋友班?
  • Klasa 不是学生的朋友班。来自 Klasa 类的方法是 Student 类的友元方法,它在 Student.h 中声明。
  • @ViteFalcon - 他没有。他宣称 Klasa 的成员是朋友:friend bool Klasa::assignToKlasa(Student* s);
  • 他并没有说他声明了整个班级为朋友,只是那个班级的一个方法
  • @SteveJessop 我认为这也是问题所在,你应该写一个答案。

标签: c++ class friend


【解决方案1】:

您对class Student { ... } 的定义也不应该编译。 friend 声明是一个错误,所以我很惊讶它也没有突出显示。您的 IDE 发现,如果没有有效的 friend 声明,则不允许访问私有成员。

错误是Klasa 的前向声明不足以将Klasa 的成员函数声明为Student 的朋友。您首先需要Klasa 的类定义。

所以,应该是:

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

class Klasa { 
    ... 
};

class Student { 
    ... 
};

那么你可以定义Klasa::assignToKlasa

【讨论】:

  • 对不起,我没有粘贴整个 student.h ,当然在 Student.h 中也有 #include #include "Klasa.h" #include "SubjectType.h" #include " SubjectGrades.h" 使用命名空间标准;
  • @MelsNoob:在这种情况下,我不确定,您可能需要生成一个自包含的问题示例。我最好的猜测是,也许你有一些循环包含,所以实际上Student 类的定义确实出现在Klasa 类的定义之前。可以肯定的是,预处理导致问题的源文件(我想是Klasa.cpp),你会看到编译器看到的确切内容。
【解决方案2】:

对于这个等效代码

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; }
};

我收到错误消息(使用 gcc 4.3.2):

test3.cc:7: 错误:不完整类型‘struct A’的无效使用

test3.cc:1: 错误:'struct A' 的前向声明

test3.cc:在成员函数'bool A::method(B*) const'中:

test3.cc:3: 错误:'int B::x' 是私有的

test3.cc:15: 错误:在此上下文中

第一个错误是唯一您必须担心的(其他错误要么是第一个错误的解释或后果)。那么如何解决这个问题呢?解决此问题的一种简单方法是通过替换将整个 class A 声明为 B 的朋友

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

  friend class A;

这是定义的。

【讨论】:

  • 我不明白,因为我是新手,你能详细解释一下吗?
  • @MelsNoob 好吧,你不能在声明A 拥有这样的成员函数之前(即在声明之前)声明类A 的成员函数为B 的朋友类A。访问失败只是一个后续错误。总是先解决第一个错误,然后再担心以后的错误,因为许多错误只是第一个错误的后果,一旦您解决了第一个错误,就会消失。
  • @Mels:这个答案与我的基本相同,但它有一个代码示例而我的没有。 “不完整类型的无效使用”与“前向声明是不够的......你需要类定义”的含义相同。类的前向声明创建一个不完整的类型,类定义创建一个完整的类型。
  • 谢谢你们 Walter 和 @Steve Jessop,所以基本上要使用另一个类的朋友方法,我需要在 1 个标题中包含这 2 个类的定义是吗?
  • @MelsNoob 。 1)要声明另一个类的成员函数为友元,编译器必须已经看到了另一个类的完整定义(可以在另一个头文件中,即#included)。 2) 要将整个类(以及它的所有成员)声明为友元,只需声明该类即可,可以是前向声明。
猜你喜欢
  • 1970-01-01
  • 2015-06-12
  • 2019-07-12
  • 1970-01-01
  • 2014-08-31
  • 2013-08-03
  • 2012-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多