一个c++问题,涉及多重继承、模板和静态变量

A C++ issue with multiple inheritance, templates and static variables

本文关键字:静态 变量 多重继承 问题 c++ 一个      更新时间:2023-10-16

我有一个类似下面的代码:

template<class ObjType>
class jsonable
{
 private:
    static map<string, jsonElem> config;
 protected:
    virtual void setConfig() = 0;
 //other fields and methods in public/private
}
class user : public jsonable<user>
{
 protected:
    virtual void setConfig();
 //other fields and methods in public/private
}
class client : user
{
 protected:
    virtual void setConfig() {user::setConfig(); /* more config */}
 //other fields and methods in public/private
}
这段代码的主要思想是在静态变量中保存与模板中引用的类相关的数据。当我想从用户类继承时,问题来了:静态变量在用户类和客户端类之间共享,而不是每个类一个静态变量。

我试过这样做:

class client : user, jsonable<client>

但是出现了一堆问题(许多方法具有相同的名称,以及其他一些与继承2次相同的类有关)。我不知道是否有一种优雅的方法来做到这一点,或者甚至根本没有一种方法。(我是c++的新手)

欢迎有任何想法!:)。当然,我可以"复制"用户的所有内容到客户端,但是…我希望在没有其他选择之前不要这样做。

编辑:

为了给这个问题添加上下文和细节,我将解释一下我正在做什么(或想做什么)。Jsonable是一个类,它提供了将另一个类序列化为Json的能力(由https://github.com/nlohmann/json帮助)。

为了实现这一点,它使用一个静态映射来存储每个json字段名称及其信息(相对于内存中类的开始的类型和位置,因此可以对其进行序列化和反序列化)。

如果一个类继承了另一个继承了jsonable的类,问题就出现了。两者都共享这个映射,因此在序列化/反序列化时只考虑基类数据。希望这个解释有助于理解……

Edit2:在一个问题中给出一个完整的代码对我来说似乎太过分了。如果有人想要编译一些东西,我已经上传了一个git repo: https://github.com/HandBe/jsontests非常感谢所有关心这个问题的人!

一个可能的解决方案可以从user(因为它是一个用户)和jsonable<client>(私有/公共分开)中导出client

class user : public jsonable<user>
{
 protected:
    virtual void setConfig();
 //other fields and methods in public/private
};
class client: public user, public jsonable<client>
{
   virtual void setConfig()
   {
       user::setConfig();
       // more config, referred to jsonable<client>::map
   }
}

因为它必须为自己实现jsonable(不管user)。

这就是所谓的"堆叠平行四边形"继承模式,作为模块化行为在多个接口实现中非常常见。

现在用户和客户端都有各自的配置

如果我正确理解你的问题:你想要clientuser,但也有所有的每类静态定义在jsonable ?

你考虑过组合而不是继承吗?

1)使user成为客户端的组件

class client : public jsonable<client>
{
    user parent; // could also be a pointer
    void setConfig() {parent.setConfig(); /* more config */}
    /* ... */
}

2)使jsonable成为组件:

class user
{
    jsonable<user> userjson; // public, private, whatever is appropriate for your design
    /* ... */
}
class client : public user
{
    jsonable<client> clientjson;
    /* ... */
}