MST

星途 面试题库

面试题:C++ 友元函数访问权限的作用域和继承问题

假设存在类 A、类 B 和类 C,类 B 是类 A 的友元类,类 C 继承自类 A。请分析友元函数在这种继承关系下对不同类成员的访问权限情况,并说明原因。如果在类 C 中重新定义了一个与类 A 中同名的私有成员,友元函数对这个新成员的访问情况又是怎样的?
37.7万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

友元函数在继承关系下的访问权限

  1. 类 B 作为类 A 的友元类
    • 类 B 的友元函数可以访问类 A 的私有和保护成员。这是因为友元关系是一种特殊的信任关系,当类 B 被声明为类 A 的友元类时,类 B 及其友元函数被赋予了访问类 A 私有和保护成员的特权。
  2. 类 C 继承自类 A
    • 友元关系不会被继承。即类 B 的友元函数不能直接访问类 C 的私有和保护成员,即使类 C 继承自类 A。这是因为友元关系是基于特定类的,而不是基于继承层次结构。每个类的友元关系是独立定义的,类 C 不会自动获得类 A 的友元的访问特权。
    • 然而,类 B 的友元函数仍然可以通过类 A 的公共接口间接访问类 C 从类 A 继承来的公有成员。例如,如果类 A 有一个公有函数 getPrivateData() 来返回其私有成员数据,类 B 的友元函数可以通过类 C 的对象调用 getPrivateData() 来间接访问类 C 从类 A 继承的相关私有数据(如果类 A 提供了这样的接口)。

类 C 中重新定义同名私有成员的访问情况

如果在类 C 中重新定义了一个与类 A 中同名的私有成员:

  1. 类 B 的友元函数不能直接访问类 C 新定义的这个同名私有成员。因为友元关系不继承,类 B 的友元函数只对类 A 的成员有访问特权,对类 C 新定义的私有成员没有访问权限。

  2. 类 B 的友元函数仍然可以访问类 A 中的同名私有成员(前提是通过类 A 的对象或指向类 A 对象的指针/引用)。这是因为其友元关系针对的是类 A,只要能获取到类 A 相关的访问对象,就可以访问类 A 的私有成员。

    例如:

#include <iostream>

class A {
private:
    int data;
    friend class B;
public:
    A(int d) : data(d) {}
};

class B {
public:
    void accessA(A& a) {
        std::cout << "Accessing A's private data: " << a.data << std::endl;
    }
};

class C : public A {
private:
    int data; // 与类 A 中的 data 同名
public:
    C(int d1, int d2) : A(d1), data(d2) {}
};

int main() {
    A a(10);
    B b;
    b.accessA(a);

    C c(20, 30);
    // b.accessA(c); // 错误,类 B 的友元函数不能直接访问类 C 的新私有成员 data
    return 0;
}

在上述代码中,B 类的 accessA 函数可以访问 A 类的 data,但不能直接访问 C 类新定义的 data