自学C++半个月遇到的问题求解,有偿

自学 C++半个月,跟着B站黑马程序员的课程,在类函数作友元时遇到了一个问题(第36行),代码的主要思路是跟着视频敲的

#include <iostream>
#include <string>
using namespace std;


class Building
{
    friend void GoodGay::visit();             //此处已经声明了GoodGay::visit()作友元
public:

    string m_sittingroom;
    Building()
    {
        m_sittingroom = "客厅";
        m_bedroom = "卧室";

    }
private:
    string m_bedroom;

};

class GoodGay
{
public:
    GoodGay()
    {
        building = new Building;

    }
    Building* building;

    void visit()
    {
        cout << building->m_sittingroom << endl;  
        cout << building->m_bedroom << endl;    //编译器在m_bedroom这里报错了,可是前面已经声明了visit()的友元地位


    }

};

int main()
{

    GoodGay gg;
    gg.visit();


}

#include <iostream>
#include <string>
using namespace std;

class Building;

class GoodGay
{
public:
    GoodGay();
    Building* building;
 
    void visit();

 
};

class Building
{
    friend void GoodGay::visit();             //此处已经声明了GoodGay::visit()作友元
public:
 
    string m_sittingroom;
    Building()
    {
        m_sittingroom = "客厅";
        m_bedroom = "卧室";
 
    }
private:
    string m_bedroom;
 
};
 
GoodGay::GoodGay()
{
    building = new Building;

}
 
void GoodGay::visit()
{
    cout << building->m_sittingroom << endl;  
    cout << building->m_bedroom << endl;    //编译器在m_bedroom这里报错了,可是前面已经声明了visit()的友元地位


}
    
int main()
{
 
    GoodGay gg;
    gg.visit();
 
 
}

img

我们将类 GoodGay的成员函数 visit 作为类 Building 的友元函数,这是我们必须在类 Building 之前声明函数visit (我们的代码,在类 GoodGay 中已经声明),在类 Building 之后定义(如果用到类 Building 的成员),在友元声明中我们必须指明该函数属于哪一个类。
因此,我们这样修改代码即可:

#include <iostream>
#include <string>
using namespace std;
class Building;

class GoodGay
{
public:
    GoodGay();
    Building* building;

    void visit();

};

class Building
{
    friend void GoodGay::visit();             //此处已经声明了GoodGay::visit()作友元
public:

    string m_sittingroom;
    Building()
    {
        m_sittingroom = "客厅";
        m_bedroom = "卧室";

    }
private:
    string m_bedroom;

};
GoodGay::GoodGay()
{
        building = new Building;

}

void GoodGay::visit()
{
        cout << building->m_sittingroom << endl;
        cout << building->m_bedroom << endl;    //编译器在m_bedroom这里报错了,可是前面已经声明了visit()的友元地位
}

int main()
{

    GoodGay gg;
    gg.visit();


}

我看了您的代码,发现您的问题是由于类的声明顺序导致的。您在Building类中声明了GoodGay::visit()作为友元函数,但是此时GoodGay类还没有定义,所以编译器无法识别GoodGay::visit()的类型。
一种解决方法是将GoodGay类的定义放在Building类的前面,然后在Building类中声明友元函数时,不需要加上GoodGay::的限定符,只需要写visit()即可。例如,您可以修改您的代码如下:

#include <iostream> #include <string> using namespace std;
class Building; // 前置声明Building类
class GoodGay { public: GoodGay() { building = new Building;
}
Building* building;
void visit(); // 声明visit函数
};

class Building { friend void visit(); // 声明visit函数作为友元 public:
string m_sittingroom;
Building()
{
    m_sittingroom = "客厅";
    m_bedroom = "卧室";
}
private: string m_bedroom;
};
void GoodGay::visit() // 定义visit函数 { cout << building->m_sittingroom << endl;
cout << building->m_bedroom << endl; // 可以访问私有成员变量
}

int main() {
GoodGay gg;
gg.visit();
}

另一种解决方法是在Building类中声明友元函数时,使用前置声明的方式,即在友元函数前加上class关键字,表示GoodGay::visit()是一个类成员函数。例如,您可以修改您的代码如下:

#include <iostream> #include <string> using namespace std;
class Building { friend class GoodGay; // 声明GoodGay类作为友元 friend void GoodGay::visit(); // 前置声明友元函数 public:
string m_sittingroom;
Building()
{
    m_sittingroom = "客厅";
    m_bedroom = "卧室";

}
private: string m_bedroom;

};

class GoodGay { public: GoodGay() { building = new Building;

}
Building* building;

void visit()
{
    cout << building->m_sittingroom << endl;  
    cout << building->m_bedroom << endl; // 可以访问私有成员变量

}

};

int main() {
GoodGay gg;
gg.visit();

}

img

代码

#include <iostream>
#include <string>

class GoodGay; 

class GoodGay  
{
public:
  GoodGay();
  ~GoodGay();
  void visit();
  class Building* building;
};

class Building
{
  friend void GoodGay::visit();
public:
  std::string m_sittingroom;
  Building();
  ~Building();
private:
  std::string m_bedroom;
};

GoodGay::GoodGay()  
{
  building = new Building;
}

GoodGay::~GoodGay()
{
  delete building;
}

void GoodGay::visit()
{
  std::cout << building->m_sittingroom << std::endl;
  std::cout << building->m_bedroom << std::endl;
}

Building::Building()
{
  m_sittingroom = "sitting room";
  m_bedroom = "bedroom"; 
}

Building::~Building()
{
}

int main()
{
  GoodGay gg;
  gg.visit();
}

编译器是从上往下分析代码
分析到friend void GoodGay::visit();的时候GoodGay还没定义
可以使用前置声明(百度),或者把GoodGay的定义放Building前面

在GoodGay类的visit()方法中访问m_bedroom属性,但是这个属性是Building类的私有属性,不能直接访问。需要将m_bedroom设置为Building类的公共属性,或者将visit()方法设置为Building类的公共方法

#include <iostream>
#include <string>
using namespace std;


class Building
{
   friend void GoodGay::visit();
public:

   string m_sittingroom;
   Building()
   {
       m_sittingroom = "客厅";
       m_bedroom = "卧室";

   }
   string m_bedroom;

};

class GoodGay
{
public:
   GoodGay()
   {
       building = new Building;

   }
   Building* building;

   void visit()
   {
       cout << building->m_sittingroom << endl;  
       cout << building->m_bedroom << endl;
   }

};

int main()
{
   GoodGay gg;
   gg.visit();
}
class GoodGay;   // 前向声明 GoodGay 类

class Building
{
    friend class GoodGay;   // 此处声明 GoodGay 为友元类
public:
    string m_sittingroom;
    Building()
    {
        m_sittingroom = "客厅";
        m_bedroom = "卧室";
    }
private:
    string m_bedroom;
};

class GoodGay
{
public:
    GoodGay()
    {
        building = new Building;
    }
    Building* building;

    void visit()
    {
        cout << building->m_sittingroom << endl;  
        cout << building->m_bedroom << endl;
    }
};

int main()
{
    GoodGay gg;
    gg.visit();
}

【以下回答由 GPT 生成】

问题的原因是在GoodGay类的visit函数中无法直接访问Building类的私有成员变量m_bedroom。虽然在Building类中声明了GoodGay类的visit函数为友元函数,但是这并不能使GoodGay类中的成员函数直接访问Building类的私有成员。

为了解决这个问题,可以通过在Building类中增加一个公有成员函数来间接访问私有成员m_bedroom。具体的解决方案如下:

  1. 在Building类中增加一个公有成员函数getBedroom(),用于获取私有成员m_bedroom的值,代码如下:
string getBedroom()
{
    return m_bedroom;
}
  1. 在GoodGay类的visit函数中调用Building类的getBedroom()函数来获取m_bedroom的值,代码如下:
void visit()
{
    cout << building->m_sittingroom << endl;
    cout << building->getBedroom() << endl;
}

修改后的完整代码如下:

#include <iostream>
#include <string>
using namespace std;

class Building
{
    friend void GoodGay::visit();
public:
    string m_sittingroom;
    Building()
    {
        m_sittingroom = "客厅";
        m_bedroom = "卧室";
    }

    string getBedroom()
    {
        return m_bedroom;
    }

private:
    string m_bedroom;
};

class GoodGay
{
public:
    GoodGay()
    {
        building = new Building;
    }
    Building* building;

    void visit()
    {
        cout << building->m_sittingroom << endl;
        cout << building->getBedroom() << endl;
    }
};

int main()
{
    GoodGay gg;
    gg.visit();
}

经过上述修改后,再次编译运行代码,即可正确输出Building类的成员变量m_sittingroom和间接访问m_bedroom的值。

希望以上解决方案能够解决你的问题。如果还有其他疑问,请随时提问。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^