利普曼5号ISBN-13: 978-0321714114
第280-281页说:
使成员函数成为朋友 与其让整个Window_mgr类成为朋友,Screen可以指定只允许透明成员访问。当我们声明一个成员函数为朋友时,我们必须指定该函数是其成员的类: 类屏幕{ // Window_mgr::clear必须在类屏幕好友Window_mgr::clear(ScreenIndex)之前声明;// .屏幕类的其余部分}; 让一个成员函数成为朋友需要仔细地构造我们的程序,以适应声明和定义之间的相互依赖。在这个例子中,我们必须按如下顺序排列我们的程序:
问题是:类Window_mgr有一个依赖于类屏幕定义的数据成员。请参见:
class Window_mgr {
public:
// location ID for each screen on the window
using ScreenIndex = std::vector<Screen>::size_type;
// reset the Screen at the given position to all blanks
void clear(ScreenIndex);
private:
std::vector<Screen> screens{Screen(24, 80, ' ')};
};因此,如果不事先定义屏幕,就不可能首先定义Window_mgr!同时,如果没有定义Window_mgr,就不可能定义屏幕!
如何解决这个问题?这本书错了吗?
我将在这里粘贴一个代码,以便您可以使用最小的代码重复这个问题:
#include <iostream>
#include <string>
#include <vector>
class A
{
friend void B::hello();
public:
A(int i) : number{i} {}
private:
void f() {
std::cout << "hello" << std::endl;
}
int number;
};
class B {
private:
std::vector<A> x{A(10)};
public:
void hello()
{
for(A &elem : x)
{
elem.f();
}
}
};
int main()
{
A x;
return 0;
}如果我编译了这段代码,结果是: error:使用未声明的标识符'B‘friend B::hello();
如果反转位置(A <-> B),我有: error:使用未声明的标识符'A‘std::向量x{A(10)};
有正确的方法吗??
谢谢!
编辑:
谢谢,克雷格·杨
解决方案:
#include <iostream>
#include <string>
#include <vector>
class A;
class B {
private:
std::vector<A> x;
public:
B();
void hello();
};
class A
{
friend void B::hello();
public:
A(int i) : number{i} {}
private:
void f() {
std::cout << "hello" << std::endl;
}
int number;
};
B::B() : x{A(10)}
{
}
void B::hello()
{
for(A &elem : x)
{
elem.f();
}
}
int main()
{
return 0;
}结论:
发布于 2018-03-19 08:47:36
一开始
好吧,你没有正确地遵循指引。
首先,定义Window_mgr类,它声明但不能定义清除。在清除之前必须声明屏幕才能使用屏幕的成员。
必须在B之前声明A。
接下来,定义类屏幕,包括用于清除的朋友声明。
现在声明A与B::hello()作为朋友。
最后,定义clear,它现在可以引用屏幕中的成员。
B:hello()可以使用A的私有成员。
在此之前已经讨论过这一点:C++ Forward declaration , friend function problem
你增加了并发症
此外,您希望B的声明引用A。要实现这一点,您需要转发声明A,以便B知道它的存在。
和--重要的是要知道,您只有对A的“部分”访问。您不能在A的声明中“充分使用”B。因此,B中的下面一行是错误的。
//You're trying to create A when you only know it exists.
//You don't have a full definition of A yet.
std::vector<A> x{A(10)};
//Replace the above with...
std::vector<A> x;当然,您必须找到另一种方法来初始化x__。
样本代码
#include <iostream>
#include <vector>
class A;
class B
{
private:
std::vector<A> x;
public:
void hello();
};
class A
{
friend void B::hello();
public:
A(int i): number(i) {}
private:
void f() { std::cout << "hello" << std::endl; }
int number;
};
void B::hello()
{
for(A &elem : x)
{
elem.f();
}
}
int main()
{
A a{5};
return 0;
}发布于 2018-03-19 04:34:11
您必须有更早的声明,而不是更早的定义。
添加
class A;
class B;前面告诉编译器,“A”和“B”指的是类。这应该足以让它推理出剩下的部分。
https://stackoverflow.com/questions/49355819
复制相似问题