You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

装饰器模式实现:派生类无法访问基类保护成员的问题求助

问题原因

C++中protected成员的访问权限有明确限制:派生类仅能访问自身对象中的基类子对象的protected成员,或者同类型派生类对象的基类子对象的protected成员。你的代码中B::func2()里调用的是a->func(),这里的a是一个独立的A实例指针,并非B自身继承的A子对象,因此编译器会判定为非法访问。

解决方案

以下是几种无需频繁修改基类A的实现方式:

方案1:给基类添加public封装接口

在A中新增一个public成员函数,封装对protected成员func()的调用。这是最符合开闭原则的方案,后续新增装饰器类无需再修改A。

#include <iostream>

class A
{
protected:
    void func() { std::cout << "func ran\n"; }
public:
    // 新增public接口,封装对func的调用
    void execute_func() { func(); }
};

class B : public A
{
public:
    void func2() { a->execute_func(); }
    A* a;
};

int main()
{
    A a;
    B b;
    b.a = &a;
    b.func2();
}

方案2:给基类添加protected辅助函数

如果不想暴露func()的public接口,可以在A中新增一个protected的辅助函数,允许派生类调用任意A实例的func()。只需修改一次A,后续所有派生装饰器都可以复用这个辅助函数。

#include <iostream>

class A
{
protected:
    void func() { std::cout << "func ran\n"; }
    // 新增protected静态函数,允许派生类操作任意A实例
    static void invoke_func(A* instance) { instance->func(); }
};

class B : public A
{
public:
    void func2() { invoke_func(a); }
    A* a;
};

int main()
{
    A a;
    B b;
    b.a = &a;
    b.func2();
}

方案3:调整装饰器的继承与持有关系

装饰器模式的标准设计中,装饰器和被装饰对象应继承同一个抽象基类。如果你可以将A设计为抽象类,让被装饰对象和装饰器都实现这个抽象接口,那么可以通过抽象接口的public方法来调用功能,从根源上避免protected访问问题。

#include <iostream>

// 抽象基类(组件)
class Component
{
public:
    virtual void do_func() = 0;
    virtual ~Component() = default;
};

// 具体组件
class A : public Component
{
protected:
    void func() { std::cout << "func ran\n"; }
public:
    void do_func() override { func(); }
};

// 装饰器
class B : public Component
{
private:
    Component* component;
public:
    B(Component* comp) : component(comp) {}
    void do_func() override 
    {
        // 可以添加装饰逻辑,再调用原组件的方法
        component->do_func();
    }
};

int main()
{
    Component* a = new A();
    Component* b = new B(a);
    b->do_func();
    
    delete b;
    delete a;
}

这种方案更贴合装饰器模式的设计初衷,同时彻底解决了访问权限问题,扩展性也更好。

内容的提问来源于stack exchange,提问作者kasra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 21:54:51