MST

星途 面试题库

面试题:C++类外访问非公有成员的特殊场景与设计考量

在一个大型C++项目中,有一个核心类`CoreClass`,其内部的非公有成员`criticalData`在特定的几个模块(ModuleA、ModuleB、ModuleC)中有访问需求,但又要严格限制其他无关模块的访问。请设计一个合理的方案,既要满足这几个特定模块对`criticalData`的访问,又要遵循C++类外访问非公有成员的代码规范,同时说明该方案的优缺点及适用场景,并用代码示例展示关键部分。
26.7万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

方案设计

  1. 友元类或友元函数
    • 可以将ModuleAModuleBModuleC对应的类声明为CoreClass的友元,这样这些类就可以访问CoreClass的非公有成员criticalData
    • 或者在CoreClass中声明特定的友元函数,这些函数在ModuleAModuleBModuleC的相关源文件中定义,通过友元函数来访问criticalData

优缺点

  1. 优点
    • 实现简单,直接利用C++的友元机制,能够快速满足特定模块访问非公有成员的需求。
    • 对原CoreClass的接口影响较小,不需要在CoreClass中额外暴露过多的公有接口。
  2. 缺点
    • 破坏了类的封装性,友元可以访问类的非公有成员,一定程度上违背了面向对象编程中数据隐藏的原则。
    • 友元关系是单向且非传递的,管理起来可能会比较复杂,如果项目结构发生变化,需要修改友元声明,维护成本可能较高。

适用场景

适用于在一个相对封闭的项目模块结构中,几个特定模块需要紧密协作,对CoreClasscriticalData有频繁访问需求,且对封装性要求不是绝对严格的场景。

代码示例

// CoreClass.h
class CoreClass {
private:
    int criticalData;
    // 声明ModuleA对应的类为友元
    friend class ModuleA;
    // 声明ModuleB对应的友元函数
    friend void accessCriticalDataFromModuleB(CoreClass* core);
public:
    CoreClass(int data) : criticalData(data) {}
};

// ModuleA.h
class ModuleA {
public:
    void accessCriticalData(CoreClass* core) {
        // 访问CoreClass的非公有成员criticalData
        std::cout << "ModuleA access criticalData: " << core->criticalData << std::endl;
    }
};

// ModuleB.cpp
#include "CoreClass.h"
#include <iostream>
void accessCriticalDataFromModuleB(CoreClass* core) {
    std::cout << "ModuleB access criticalData: " << core->criticalData << std::endl;
}
// main.cpp
#include "CoreClass.h"
#include "ModuleA.h"
#include <iostream>

int main() {
    CoreClass core(10);
    ModuleA moduleA;
    moduleA.accessCriticalData(&core);
    accessCriticalDataFromModuleB(&core);
    return 0;
}