【发布时间】:2018-08-27 14:11:25
【问题描述】:
李普曼 5th ISBN-13:978-0321714114
第 280-281 页,上面写着:
让成员函数成为朋友
与其让整个 Window_mgr 类成为朋友,Screen 可以 而是指定只允许 clear 成员访问。什么时候我们 声明一个成员函数为友元,我们必须指定类 该函数是哪个成员:
class Screen { // Window_mgr::clear must have been declared before class Screen friend void Window_mgr::clear(ScreenIndex); // ... rest of the Screen class };使成员函数成为朋友需要仔细构造我们的 适应宣言和宣言之间相互依存关系的计划 定义。在这个例子中,我们必须按如下顺序排列我们的程序:
- 首先,定义Window_mgr 类,它声明但不能定义clear。必须在 clear 之前声明 screen 才能使用 Screen 的成员。
- 接下来,定义类 Screen,包括一个用于 clear 的友元声明。
- 最后定义clear,现在可以引用Screen中的成员了。
问题是:类 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, ' ')};
};
所以不定义Screen就不可能先定义Window_mgr 之前! 同时,如果没有我们定义 Screen 是不可能的 定义了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;
}
如果我编译这段代码,结果是: 错误:使用未声明的标识符“B” 朋友 void B::hello();
如果我反转位置(A B),我有: 错误:使用未声明的标识符“A” std::vector 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;
}
结论:
- 这本书是不完整的,因为它没有揭示首先进行 A 类的前向声明的必要性,以及在这种情况下不可能进行类内初始化。
- 我没有注意到问题是 A(10),而不是向量!也就是说,当我们将它用作向量的模板参数时,我们可以使用不完整类型 A(仅声明,没有定义)(因为它本身不会创建 A 对象),但在定义对象时不能使用不完整类型 A,例如:A(10);
【问题讨论】:
标签: c++