【问题标题】:C++ decorator: Access public function of base class from outsideC++ 装饰器:从外部访问基类的公共函数
【发布时间】:2020-07-10 19:44:19
【问题描述】:

我想尝试使用 C++ 装饰器,但我有一些问题。

使用这个例子:https://gist.github.com/dlivingstone/3006324#file-decoratormain-cpp

class AbstractNPC {
public:
    virtual void render() = 0;
};

class NPC: public AbstractNPC {
public:
    NPC() { }
    render(){...}
};

class NPCDecorator: public AbstractNPC {
private:
    AbstractNPC * npc;
public:
    NPCDecorator(AbstractNPC *n) { npc = n; }
    void render() { npc->render(); } // delegate render to npc data member
};

class Elite: public NPCDecorator {
public:
    Elite(AbstractNPC *n): NPCDecorator(n) { }
    void render() {
        cout << "Elite "; // render special features
        NPCDecorator::render(); // delegate to base class
    }
};

int main(){
    AbstractNPC *goblin1= new Elite(new Shaman(new NPC("Goblin")));
    ...
}

我是否必须在 AbstractNPC 中将每个函数设为虚拟并从 NPCDecorator 重定向它以从外部调用它?

class NPC: public AbstractNPC {
public:
    NPC();
    void render() {...}
    void func1() {...}
    void func2() {...}
    void func3() {...}
    void func4() {...}
    void func5() {...}
};
int main(){
    AbstractNPC *goblin1= new Elite(new Shaman(new NPC("Goblin")));
    call func1(); ???
}

【问题讨论】:

    标签: c++ class decorator


    【解决方案1】:

    这里的NPC 类应该是一个具体类,具有所有虚函数的真实实现。它可以是最小的简单 NPC,其中实现是基本逻辑,如果根本没有应用装饰器,则应该使用它。请注意,它甚至没有要重定向到的指针成员。

    NPCDecorator 类应该具有将所有公共接口虚拟调用重定向到其npc 指针成员的函数。

    EliteShaman 这样的特定装饰器只需要定义它们改变行为的虚函数。如果Elitefunc2 的作用没有影响,则它可以完全跳过声明和定义func2,因为它将在基类NPCDecorator 中可见。

    我肯定会在这里将所有指向std::unique_ptr 的指针和所有new 表达式更改为std::make_unique,以避免编写手动清理代码和潜在的大量错误和令人头疼的问题。

    【讨论】:

    • hm,采用这样的方案,作为 RCTP 基础的具体类的装饰器不是更谨慎吗?我看不出动态调用对这种情况有什么好处?
    • @Swift-FridayPie 可能。我没有写这个,只是试图解释链接的例子最有可能被使用。直接 CRTP 的一个问题是您不能使用常量接口类型,并且几乎每个函数都需要作为模板。但可能会有一些相当不错的方法将 CRTP 与类型擦除结合起来,以改进整个模式并消除所有嵌套指针重定向。
    猜你喜欢
    • 2011-05-17
    • 2014-01-25
    • 2020-05-02
    • 2011-09-22
    • 2017-03-28
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 2011-06-25
    相关资源
    最近更新 更多