我只是想知道以下代码发生了什么:
class SomeClass {
public:
void someMethod();
private:
bool _someValue;
}
class SomeOtherClass {
friend class SomeClass;
public:
void someOtherMethod();
private:
bool _someOtherValue;
}
我在'朋友课'中已经阅读了以下页面,看起来朋友类可以访问定义类了吗? http://www.cplusplus.com/doc/tutorial/inheritance/
如果是这种情况,使用friend class SomeClass
和继承class SomeOtherClass : SomeClass { }
答案 0 :(得分:5)
“有权访问私有成员”和“被组成 a”之间存在差异(编辑:实际上是作文是另一回事)。
#include <iostream>
class B;
class A {
friend class B;
private:
int x;
};
class B {
static void print(const A& a) {
// A::x is private, but B is a friend of A, so it's fine
std::cout << a.x << std::endl;
}
};
int main() {
A a;
B::print(a);
return 0;
}
这是合法的。 A::x
是私有的,但B
的方法可以使用它A
声明B
是朋友类,可以访问其私有/受保护成员。但是,B
不是A
,特别是B
是一个空类(这就是为什么你必须传递A
来打印)。
#include <iostream>
class A {
private:
int x;
};
class B : public A {
void print() {
// error A::x is private!
std::cout << A::x << std::endl;
}
};
int main() {
B b;
b.print();
return 0;
}
这是非法的。 B
继承自A
,但它不会授予他对其私有成员的任何访问权限,即使它实际上包含它们。 B
不再为空,实际上包含A
的实例(因此A::x
,但它无法访问它)
#include <iostream>
class A {
protected:
int x;
};
class B : public A {
void print() {
// A::x is protected, but B inherits from A, so it's fine
std::cout << A::x << std::endl;
}
};
int main() {
B b;
b.print();
A a;
// error a::x is protected and can only be accessed from A or from any class which inherits from A
// std::cout << a.x << std::endl;
return 0;
}
这是合法的。 B
可以访问受保护的成员A::x
,因为它继承自A
,B
也是A
,实际上是非空的。
答案 1 :(得分:2)
Inherit
意味着太多事情,它与friend
无关。
只关注访问权限,友元类可以访问定义类的public / protected / private成员,而派生类只能访问基类的public / protected成员。
答案 2 :(得分:2)
通过继承派生类将包括基类的内存布局。如果base有一个整数,则意味着你的派生类也会有它。
class A
{
int a1;
};
class B : public A
{
int b1 ;
};
B b; sizeof(b)现在是8个字节,因为它还包含A的变量。
朋友类与基类内存布局无关,它们不具备基类所具有的内容。朋友声明只会帮助您进行访问控制。这意味着如果B类有一个A类指针:
class B : public A
{
int b1 ;
A *a;
void foo()
{
std::cout << a->a1; --> possible because B is a friend of A
}
}
如果可以的话,请避免朋友的诽谤,因为隐藏信息是好的。
答案 3 :(得分:1)
友谊是一种黑客攻击。它允许A类给出B类某些的对象,如果它继承自A类,它将会做的那种访问。但是,这两个特征并不相同。
一个区别是,继承类只能访问基类的public
和protected
成员,而受限制的类可以完全访问所有内容,包括private
成员。
友谊不会形成继承层次,因此无法实现新的转换。类型为B
的对象不会自动拥有来自A
类型的子对象的成员;它只是他们能够访问类型为A
的任意对象的成员,如果他们可以在某处看到它。
friend
就像向某人提供您的所有银行详细信息