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

如何创建共享相同成员的Mixin类?解决多继承段错误问题

如何创建可共享相同成员的Mixin类?

我明知这可能是不佳的设计选择,但已是最后方案。以下是示例代码(注意其中的指针并未共享):

struct Full{
    int a = 213;
    int b = 500;
    int c = 400;
};

struct ProxyA{
    std::shared_ptr<Full> full;
    void say_a(){
        std::cout << full->a;

    }
};

struct ProxyB{
    std::shared_ptr<Full> full;

    void say_b(){
        std::cout << full->b;

    }
};

struct FullProxy: public ProxyA, public ProxyB{
    std::shared_ptr<Full> full;
    FullProxy(std::shared_ptr<Full> full_):
    full{full_}{};
    void say_c(){
        std::cout << full->c << "\n";
    }
};


int main() {
    FullProxy foo(std::make_shared<Full>());
    foo.say_a();
    foo.say_b();
    foo.say_c();
}

运行输出:

ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 139
Program terminated with signal: SIGSEGV

注:我无法使用模板,因为这些类需要包含Q_PROPERTY,而Qt不支持模板。
我意识到Qt不支持多继承,因此该方案无法在Qt中使用。


问题根源

代码崩溃是因为ProxyA和ProxyB中的full指针从未被初始化——FullProxy的构造函数只初始化了自身的full成员,基类的full仍为空指针,调用say_a()/say_b()时访问空指针触发段错误。同时当前设计存在冗余:三个shared_ptr指向同一个对象,完全没必要。

可行解决方案

方案1:初始化基类成员(简单但冗余)

直接在FullProxy的构造函数中显式初始化基类的full指针:

struct FullProxy: public ProxyA, public ProxyB{
    std::shared_ptr<Full> full;
    FullProxy(std::shared_ptr<Full> full_):
    ProxyA{full_}, ProxyB{full_}, full{full_}{};
    void say_c(){
        std::cout << full->c << "\n";
    }
};

这种方式能解决崩溃问题,但每个基类和派生类都持有一份shared_ptr,存在冗余。

方案2:虚拟继承共享成员(消除冗余)

定义一个持有共享成员的基类,让所有Mixin类虚拟继承它,确保整个继承体系中只有一份共享成员实例:

struct FullHolder {
    std::shared_ptr<Full> full;
    FullHolder(std::shared_ptr<Full> full_) : full(std::move(full_)) {}
    std::shared_ptr<Full> get_full() const { return full; }
};

struct ProxyA: virtual public FullHolder{
    using FullHolder::FullHolder; // 继承构造函数
    void say_a(){
        std::cout << get_full()->a;
    }
};

struct ProxyB: virtual public FullHolder{
    using FullHolder::FullHolder;
    void say_b(){
        std::cout << get_full()->b;
    }
};

struct FullProxy: public ProxyA, public ProxyB{
    FullProxy(std::shared_ptr<Full> full_): FullHolder(std::move(full_)), ProxyA(full_), ProxyB(full_){}
    void say_c(){
        std::cout << get_full()->c << "\n";
    }
};

所有Mixin类都通过FullHolder获取共享的full指针,彻底避免了冗余。

方案3:组合替代继承(适配Qt限制)

由于Qt不支持多继承,改用组合方式,把Mixin类作为成员变量,在FullProxy中转发调用:

struct FullProxy{
    std::shared_ptr<Full> full;
    ProxyA proxy_a;
    ProxyB proxy_b;

    FullProxy(std::shared_ptr<Full> full_): full(std::move(full_)), proxy_a{full}, proxy_b{full}{}

    // 转发调用
    void say_a() { proxy_a.say_a(); }
    void say_b() { proxy_b.say_b(); }

    void say_c(){
        std::cout << full->c << "\n";
    }
};

这种方式完全避开多继承,符合Qt的要求,同时保证所有组件共享同一个full指针。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 06:02:14