MST

星途 面试题库

面试题:C++中利用访问者模式访问类的私有成员

请描述在C++中如何运用访问者模式来访问类的私有成员。假设存在一个`Element`类及其子类,这些类中有私有成员需要被特定的访问者访问,写出实现这个场景的主要代码框架,并阐述访问者模式在此场景中的优势与适用场景。
40.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

代码框架

  1. 定义访问者接口
class Visitor {
public:
    virtual void visitElement1(Element1* element) = 0;
    virtual void visitElement2(Element2* element) = 0;
    // 其他具体元素的访问方法
};
  1. 定义元素基类和具体元素类
class Element {
public:
    virtual void accept(Visitor* visitor) = 0;
};

class Element1 : public Element {
private:
    int privateData1;
public:
    Element1(int data) : privateData1(data) {}
    void accept(Visitor* visitor) override {
        visitor->visitElement1(this);
    }
    // 提供获取私有成员的方法(仅为示例,实际可按需调整)
    int getPrivateData1() {
        return privateData1;
    }
};

class Element2 : public Element {
private:
    double privateData2;
public:
    Element2(double data) : privateData2(data) {}
    void accept(Visitor* visitor) override {
        visitor->visitElement2(this);
    }
    // 提供获取私有成员的方法(仅为示例,实际可按需调整)
    double getPrivateData2() {
        return privateData2;
    }
};
  1. 定义具体访问者类
class ConcreteVisitor : public Visitor {
public:
    void visitElement1(Element1* element) override {
        int data = element->getPrivateData1();
        // 处理数据
    }
    void visitElement2(Element2* element) override {
        double data = element->getPrivateData2();
        // 处理数据
    }
};
  1. 使用访问者模式
int main() {
    Element1* element1 = new Element1(10);
    Element2* element2 = new Element2(3.14);

    Visitor* visitor = new ConcreteVisitor();
    element1->accept(visitor);
    element2->accept(visitor);

    delete element1;
    delete element2;
    delete visitor;
    return 0;
}

优势

  1. 分离数据操作和数据结构:访问者模式将对数据的操作从数据结构中分离出来,使得数据结构和操作可以独立变化。例如,当需要对Element及其子类的私有成员进行新的操作时,不需要修改Element类及其子类的代码,只需添加新的访问者类。
  2. 增加新操作的灵活性:方便在不改变现有类层次结构的情况下,增加新的操作。如果没有访问者模式,每次添加新操作都可能需要修改Element类及其子类,违反开闭原则。
  3. 集中相关操作:将相关的操作集中在访问者类中,使代码结构更清晰,更易于维护和理解。

适用场景

  1. 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类型的操作:比如Element类及其多个子类,不同子类有不同的私有成员,希望对不同子类的私有成员执行不同操作。
  2. 需要对一个对象结构中的对象进行很多不同且不相关的操作,而你想避免让这些操作“污染”这些对象的类:将操作封装在访问者类中,保持对象类的简洁。
  3. 当对象结构的类很少改变,但经常需要在此结构上定义新的操作时:因为使用访问者模式可以在不修改对象结构类的前提下添加新操作。