C 阶级友谊
C++ class friendship
我正在编写代码以通过另一个朋友类访问类的私人成员。以下代码工作
// Example program
#include <iostream>
#include <string>
using namespace std;
class Foo
{
private:
int a;
protected:
public:
friend class Bar;
Foo(int x)
{
a = x ;
}
};
class Bar
{
private:
protected:
public:
int b;
Bar(Foo& f)
{
b = f.a;
cout << "f.a is " << f.a << endl;
}
};
int main()
{
Foo foo(5);
Bar bar(foo);
cout << "Value of variable b is " << bar.b << endl;
}
上面的代码正常工作。但是,如果我想通过朋友类Bar
中的函数访问Foo
的私有变量,我将无法。请参阅下面的代码
#include <iostream>
#include <string>
using namespace std;
class Foo
{
private:
int a;
protected:
public:
friend class Bar;
Foo(int x)
{
a = x ;
}
};
class Bar
{
private:
protected:
public:
int b;
Bar(Foo& f)
{
b = f.a;
}
void printvariable(void)
{
cout << "f.a is " << f.a << endl;
}
};
int main()
{
Foo foo(5);
Bar bar(foo);
cout << "Value of variable b is " << bar.b << endl;
}
我完全理解为什么执行失败
void printvariable(void)
{
cout << "f.a is " << f.a << endl;
}
函数由于f不在函数范围内。但是,由于我在Bar b
的构造函数中传递了Foo f
,因此我希望编写代码,使我能够访问Foo
中的成员,而无需将Foo f
再次传递给函数printvariable()
。
编写此代码的最有效方法是什么?
您可以保留对f
的引用。代码应为:
class Bar
{
private:
protected:
public:
int b;
Foo& f_ref;
Bar(Foo& f)
:f_ref(f)
{
b = f.a;
}
void printvariable(void)
{
cout << "f.a is " << f_ref.a << endl;
}
};
测试!
您可以这样做,但是如果我是您,您也会写一些Getters,也不是真正推荐的班级友谊。
class Bar {
public:
Foo& ref;
Bar(Foo& f)
: ref { f }
{ }
void printvariable() {
cout << "f.a is " << ref.a << endl;
}
};
顺便说一句,没有理由在C 的括号中添加void
,它失去了C的含义,现在没有效果。
您在某个点上错了。您确实在CTOR中传递了对f
的引用,但是构造函数和整个class Bar
不记得 a f
的整个整个对象。在您的原始代码中,构造函数仅使栏对象记住对象的int a
部分,因此后来可以访问一点点:
class Foo
{
...
friend class Bar;
...
};
class Bar
{
...
int b;
Bar(Foo& f)
{
b = f.a; // <=--- HERE
}
void printvariable(void)
{
cout << "f.a is " << b << endl; // <-- now it refers B
}
请注意,您的bar的CTOR如何仅读取f.a
并将其存储在b
中。从现在开始,条对象只会记住b
,仅此而已。您可以在printvariable
中自由访问b
。但是,它不会是 a
-taken-from- f
。它将是b
,将其设置为与构造函数期间F.A相同的值。由于那个时间点,b
和f.a
是完全分开的。这就是价值复制的工作方式。
要使酒吧记住整个 f
,您必须,请记住整个 f:
class Bar
{
...
Foo wholeThing;
Bar(Foo& f)
{
wholeThing = f; // <=--- HERE
}
void printvariable(void)
{
cout << "f.a is " << wholeThing.a << endl;
}
但是,同样,有一个捕获:现在,由于wholeThing
是Foo
类型,因此构造函数实际上将在wholeThing=f
期间复制该对象。与b=f.a
时一样,但现在它记得整个f。
当然,这只是类型问题。您可以存储一个参考而不是全面的参考,但是它需要一些不同的初始化语法:
class Bar
{
...
Foo& wholeThing;
Bar(Foo& f) :
wholeThing(f) // <=--- HERE
{
// <=--- empty
}
void printvariable(void)
{
cout << "f.a is " << wholeThing.a << endl;
}