类定义中的c ++ friend class关键字

时间:2015-07-31 15:03:25

标签: c++ class

我只是想知道以下代码发生了什么:

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 { }

等类之间有什么区别?

4 个答案:

答案 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,因为它继承自AB也是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类,它将会做的那种访问。但是,这两个特征并不相同。

一个区别是,继承类只能访问基类的publicprotected成员,而受限制的类可以完全访问所有内容,包括private成员。

友谊不会形成继承层次,因此无法实现新的转换。类型为B的对象不会自动拥有来自A类型的子对象的成员;它只是他们能够访问类型为A的任意对象的成员,如果他们可以在某处看到它。

  • friend就像向某人提供您的所有银行详细信息
  • 继承就像设置联合帐户