自学 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();
}
我们将类 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();
}
代码
#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。具体的解决方案如下:
string getBedroom()
{
return 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的值。
希望以上解决方案能够解决你的问题。如果还有其他疑问,请随时提问。
【相关推荐】