简体   繁体   English

具有多重继承、模板和静态变量的 C++ 问题

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

I have a code similar to the following:我有一个类似于以下的代码:

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
}

The main idea of this code is to save in static variables data related to the class referenced in the template.这段代码的主要思想是将与模板中引用的类相关的数据保存在静态变量中。 The problem comes when I want to inherit from the user class: the static variable is shared between user and client classes, instead of one static variable for each class.当我想从用户类继承时,问题就出现了:静态变量在用户类和客户端类之间共享,而不是每个类都有一个静态变量。

I've tried to do something like:我试过做这样的事情:

class client : user, jsonable<client>

But a bunch of problems appeared (many methods with same name, and some other related to inherit 2 times the same class).但是出现了一堆问题(许多方法同名,还有一些与继承同一个类的2次有关)。 I don't know if there is an elegant way of do this, or even if there is a way at all.我不知道是否有一种优雅的方式来做到这一点,或者根本没有办法。 (I'm a bit newbie in c++) (我是 C++ 的新手)

Any idea would be welcome!欢迎任何想法! :). :)。 And of course, I can "copy" all the contents of user into client but... I would like to do not do that until there are no more options.当然,我可以将用户的所有内容“复制”到客户端,但是......在没有更多选择之前,我不想这样做。

Edit: In order to add context and details to the question, I'm going to explain a bit what I'm doing (or want to do).编辑:为了向问题添加上下文和细节,我将解释一下我在做什么(或想要做什么)。 Jsonable is a class that provides the ability to serialize into Json another class (helped by https://github.com/nlohmann/json ). Jsonable 是一个类,它提供了将另一个类序列化为 Json 的能力(由https://github.com/nlohmann/json帮助)。

To achive this, it uses a static map to store each jsonable-field name and its info (type and position relative to the start of the class in memory, so it can be serialized and deserialized).为了实现这一点,它使用一个静态映射来存储每个 jsonable-field 名称及其信息(类型和位置相对于内存中类的开头,因此它可以被序列化和反序列化)。

The problem comes if a class inherits from another class that inherits from jsonable.如果一个类继承自另一个从 jsonable 继承的类,就会出现问题。 Both shares that map, so only the baseclass data is consider when serializing/deserializing.两者共享该映射,因此在序列化/反序列化时仅考虑基类数据。 Hope this explanation helps to understand...希望这个解释有助于理解......

Edit2 : Giving a full code in a question seems very overkilling to me. Edit2 :在问题中给出完整代码对我来说似乎太过分了。 If someone wants something to compile, I've uploaded a git repo: https://github.com/HandBe/jsontests Really thanks to all the people who have put interest on this question!.如果有人想要编译一些东西,我已经上传了一个 git repo: https : //github.com/HandBe/jsontests真的感谢所有对这个问题感兴趣的人!。

A possible solution can be derive client from both user (because it is a user) and jsonable<client> as (private/public apart)一个可能的解决方案可以是从user (因为它是用户)和jsonable<client> as(私有/公共分开)派生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
   }
}

because it has to implement jsonable for itself (regardless of user ).因为它必须为自己实现 jsonable (不管user )。

This is the so-called "stacked parallelogram" inhertiance pattern very common in multiple interface implementations as modular behavior.这是所谓的“堆叠平行四边形”继承模式,作为模块化行为在多个接口实现中非常常见。

Now user and client have each their own configuration现在用户和客户端都有自己的配置

If I understand your problem correctly: you want client to be a user , but also have all the per-class statics defined in jsonable ?如果我正确理解您的问题:您希望client成为user ,但还具有在jsonable定义的所有类静态jsonable

Have you considered composition over inheritance?你考虑过组合而不是继承吗? This could work either way:这可以以任何一种方式工作:

1) make user a component of client 1)使user成为客户端的组件

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

2) make jsonable a component: 2) 使jsonable成为一个组件:

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

class client : public user
{
    jsonable<client> clientjson;
    /* ... */
}      

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM