MST

星途 面试题库

面试题:C++友元关系在复杂类层次结构中的应用

假设有一个类层次结构,基类`Base`有一些私有成员,派生类`Derived`继承自`Base`。现在要在另一个类`Helper`中通过友元关系访问`Base`和`Derived`的私有成员,应该如何设计和实现?请写出相关代码,并阐述这样设计可能带来的问题及解决方案。
13.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

代码实现

#include <iostream>

class Base {
    friend class Helper;
private:
    int basePrivate;
public:
    Base(int value) : basePrivate(value) {}
};

class Derived : public Base {
    friend class Helper;
private:
    int derivedPrivate;
public:
    Derived(int baseVal, int derivedVal) : Base(baseVal), derivedPrivate(derivedVal) {}
};

class Helper {
public:
    void accessBasePrivate(Base& base) {
        std::cout << "Accessing Base's private member: " << base.basePrivate << std::endl;
    }
    void accessDerivedPrivate(Derived& derived) {
        std::cout << "Accessing Derived's private member: " << derived.derivedPrivate << std::endl;
    }
};

测试代码

int main() {
    Base base(10);
    Derived derived(20, 30);
    Helper helper;
    helper.accessBasePrivate(base);
    helper.accessDerivedPrivate(derived);
    return 0;
}

设计带来的问题

  1. 破坏封装性:友元关系允许Helper类直接访问BaseDerived的私有成员,这打破了类的封装性原则,使得类的内部实现细节对外部类可见,增加了代码维护的难度和潜在的风险。
  2. 耦合度增加Helper类与BaseDerived类紧密耦合,BaseDerived类的私有成员的任何改变都可能影响到Helper类,降低了代码的可维护性和可扩展性。

解决方案

  1. 最小化友元使用:尽量减少友元类的数量,仅将需要访问私有成员的最必要的类设为友元,避免过度暴露私有成员。
  2. 接口替代友元:在BaseDerived类中提供公共接口来间接访问私有成员,这样既保证了封装性,又能满足外部类对内部数据的特定操作需求。例如:
class Base {
private:
    int basePrivate;
public:
    Base(int value) : basePrivate(value) {}
    int getBasePrivate() const {
        return basePrivate;
    }
};

class Derived : public Base {
private:
    int derivedPrivate;
public:
    Derived(int baseVal, int derivedVal) : Base(baseVal), derivedPrivate(derivedVal) {}
    int getDerivedPrivate() const {
        return derivedPrivate;
    }
};

class Helper {
public:
    void accessBasePrivate(const Base& base) {
        std::cout << "Accessing Base's private member: " << base.getBasePrivate() << std::endl;
    }
    void accessDerivedPrivate(const Derived& derived) {
        std::cout << "Accessing Derived's private member: " << derived.getDerivedPrivate() << std::endl;
    }
};

通过这种方式,Helper类通过公共接口访问BaseDerived的私有数据,维护了类的封装性,同时也降低了耦合度。