无法使用好友类的方法

unable to use friend class' method

本文关键字:方法 好友      更新时间:2023-10-16

我的代码有问题。我有两个类,Run和Robot,我希望Robot类型的对象更改Run类型对象的私有成员。具体来说,我想在下面的代码中增加"x"的值。

弹出以下错误:

错误:未在此作用域中声明"getX"错误:未在此作用域中声明"getX"

我用箭头(<---)指出了错误发生的那一行。下面的代码只是一个测试,只是为了学习如何在项目中使用"friend"关键字。

#include <iostream>
#include <vector>
using namespace std;
class Robot;
class Run{
    friend class Robot;
private:
    int x;
    vector<Robot*>robots;
public:
    Run();
    vector<Robot*>*getRobots();
    void createRobot();
    void movAll();
    void setX(int);
    int getX();
};
class Robot{
    friend class Run;
public:
    Robot();
    void movingRobot();
};
Run::Run(){}
vector<Robot*>*Run::getRobots(){return &robots;}
void Run::createRobot(){getRobots()->push_back(new Robot);setX(1);}
void Run::movAll(){getRobots()->at(0)->movingRobot();}
int Run::getX(){return x;}
void Run::setX(int c){x=c;}
Robot::Robot(){}
void Robot::movingRobot(){setX(getX()+1);}    <-------------------------
int main(){
    Run Sim;
    Sim.createRobot();
    Sim.movAll();
}

使用"friend"关键字肯定会对我的项目有所帮助,所以我正在努力了解如何使用它。

您只是调用getX()setX(),就好像它们是Robot的方法一样。您需要针对Run的实例调用该函数,在这种情况下,您不需要将其作为朋友,因为getX()无论如何都是公共的。

也就是说,你希望每个机器人都有一个x值,你想增加它吗?在这种情况下,您需要它是Robot的成员,而不是Run。

如果您希望Run具有一个值x,Robot的所有实例都可以访问和修改,那么只需将x设置为静态,然后直接访问它,而不是调用公共方法,因为公共方法不需要另一个类作为朋友。

您调用getX,就好像它是Robot类的函数一样。您需要一个运行对象来调用它:

run.getX()

好的,您可以从Robot类中删除getX()函数,因为它目前没有代码体,对于内部使用,robot类可以始终使用其X变量。Run不需要有friend class Robot,因为Robot不需要查看Run中的任何内容,并且由于Run包含指向Robot实例的指针向量,它可以通过查看其向量的内容来访问Robot实例的任何值(例如,myRunInstance.getRobots()[1]->getX()将返回Robot向量中第二个Robot的x值)。

现在,如果getX函数要保留在Run类中,它就必须有一点变化:您需要指定一种方法,使它收集Robot类的特定实例的信息,可能是从它的Robots向量中收集信息。我重新编译了你上面的代码,并在主代码中添加了一个小的概念验证代码集,让10个机器人使用moveall将它们全部移动,然后将Johnny5设置到一个特殊的地方(因为他很特殊:)大致如下:

#include <iostream>
#include <vector>
using namespace std;
class Run;

class Robot{
    friend class Run;   // allows the Run class to access all the private data as if it were its own
    private:
        int x;
    public:
        Robot() {};
        void setX(int newX) {   x= newX;    }
        int getX()          {   return x;   }
        void movingRobot()  {   x+=1;   }
};
class Run{
private:
    vector<Robot*> robots;
public:
    Run(){};
    vector<Robot*> *getRobots() {   return &robots; }
    void createRobot()          {   robots.push_back(new Robot()); robots.back()->x =1; }
    void movAll()               {   for (int i=0;i<robots.size();i++){ robots[i]->movingRobot();}   }
    int getX(int robotPosition){    return robots[robotPosition]->x;    }  //uses the friend status to read directly from Robot class instances x
    void setX(int rpos, int xval){  robots[rpos]->setX(xval);   }
};

int main()
{
    Run *Sim = new Run();
    for (int i =0; i< 10; i++)
        {
            Sim->createRobot();
            Sim->setX(i,i); // uses the Run setX
            std::cout << "Robot " << i << "(starting position): " << Sim->getRobots()->at(i)->getX() << std::endl;
        }
    Sim->movAll();
    // lets move Johnny 5 to 55 as well...
   (Sim->getRobots()->at(4))->setX(55); // uses the robot setx
    for (int i=0; i< 10; i++)
    {
        std::cout << "Robot " << i << "(final position): " << Sim->getRobots()->at(i)->getX()<< std::endl;
    }

    return 0;
}

源代码也可在Ideone 上查看样本输出