【问题标题】:Why can't this friend function access the private variables?为什么这个友元函数不能访问私有变量?
【发布时间】:2013-06-18 15:06:02
【问题描述】:
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();

}

函数 printResult 似乎无法从 Student 类访问私有变量 allow。我是在错误的地方对 printResult 进行原型制作还是语法错误? AFAIK,我们可以在课堂上的任何地方为朋友制作原型。

【问题讨论】:

  • 你得到的确切错误是什么?

标签: c++ class friend


【解决方案1】:

printResult 不是成员函数,所以你需要给它一个Student 实例来操作。例如

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

然后

Student student(1);
printResult(student);

【讨论】:

    【解决方案2】:

    这是因为allow 属于该类的一个实例,但没有引用任何实例。

    您可能应该将printResult 设为类的成员函数,而不是将其设为外部函数或让该函数引用Student 实例,以便您可以访问@987654324 @ 成员通过instance.allow ,其中instance 是const Student&amp; 类型的参数。

    【讨论】:

      【解决方案3】:

      下面是一些有效的代码:

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

      我对其进行了修改以将打印功能保留在全局空间中(仅基于您想要的外观)。它需要一个 Student* 参数,因为它被声明为朋友,所以它会看到“允许”变量。然而,这不是您想要滥用的 C++ 的一部分。小心你如何使用朋友。在更大的代码库中像这样使用它是危险的。全局功能通常不是要走的路。将 print 函数作为学生类中的公共成员函数可能是一种更好的做事方式。其他答案提供了显示该实现的代码。我决定向您展示此实现,因为它似乎更接近您在问题中寻找的内容。

      我还确保在提及 cout 和 endl 时使用 'std::'。这消除了对“使用命名空间标准;”的需要在顶部。这只是在更复杂的项目中的良好编程实践。

      【讨论】:

      • 感谢您的额外提示!我需要时间来研究您所做的更改...非常有用的答案!
      • 您可能要考虑的另一件事是以不同的方式进行输入。如果你给它意外的数据,一个裸露的 cin >> 可能会失败,从而丢掉你程序的其余部分。
      【解决方案4】:
      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()   
      }
      

      【讨论】:

        【解决方案5】:

        允许类友函数访问类实例的成员。 您应该将实例传递给函数,例如:

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

        【讨论】:

        • 传递一个副本,这是不需要的。使函数采用 const Student&amp; 代替。 (除了参数列表,您无需更改任何内容)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-04
        • 2012-11-20
        • 1970-01-01
        • 2021-11-01
        • 2023-03-24
        • 2013-06-30
        • 1970-01-01
        相关资源
        最近更新 更多