基于类的类型的引用计数实例

如何解决基于类的类型的引用计数实例

| 考虑以下代码:
struct I
{
    SomeInternalState m_internalState;
};

struct S
{
    I * m_i;
    set_I (I * i)
    {
        m_i = i;
        makeSomeChangesToTheInternalStateOfI(m_i);
    }
};

struct S_1 : S { ... };
struct S_2 : S { ... };
...
struct S_n : S { ... };
假定可以创建任意数量的
S_1
,...
S_n
实例,并且它们全部将仅调用
set_I()
一次。 现在,我希望每个类型
S_x
的每个
I
实例的
S_1
,... ...2ѭ到
makeSomeChangesToTheInternalStateOfI()
实例一次,这样我就可以从相同类
S_x
的不同实例和相同的
I
实例中调用
set_I()
,并确保ѭ7'的内部状态仅在第一次通话时才被修改。 可能的决定是将一些分配表放入ѭ7中,但我认为它不是一个明智的键,仅基于
S_x
实例的类型并且不涉及任何手写的“运行时类型id”常量所有可能的类型
S_1
,...
S_n
。 我该怎么做? 编辑: 我应该强调的几点: 1)一次可能会有一个以上的ѭ7instance实例,并且
S_x
类应该能够更改
I
的多个实例的状态,但每个实例只能更改一次。那是:
I i1,i2;
S_1 s1a,s1b;
S_2 s2a,s2b;

// all possible combinations:
s1a.changeStateOfI(i1);
s1b.changeStateOfI(i1);
s2a.changeStateOfI(i1);
s2b.changeStateOfI(i1);
s1a.changeStateOfI(i2);
s1b.changeStateOfI(i2);
s2a.changeStateOfI(i2);
s2b.changeStateOfI(i2);
在此片段中,ѭ21和22的状态仅应通过ѭ1方法(通过ѭ24)更改一次,并通过by25'(通过'26ѭ)更改一次。 2)我想,可以使用引用计数来解决问题-无需确切知道初始化发生了多少次,就足以知道是否进行了初始化。 编辑2 我将n.m.的建议标记为答案,尽管我的最终解决方案有所不同。在这里,以便其他人也可以使用它:
struct AbstractS
{
    I * m_i;
    virtual void set_I (I * i) = 0;
};


template <typename self_T>
struct RegS : AbstractS
{
    static std::set<I *> s_registeredContexts;

    virtual void set_I (I * i)
    {
        m_i = i;

        if (i == NULL || s_registeredContexts.count(i) > 0) return;

        makeSomeChangesToTheInternalStateOfI(i);
        contexts.insert(i);
    }
};

template <typename self_T>
std::set<I *> InterpreterState<self_T>::s_registeredContexts;


struct S_1 : RegS<S_1> { ... };
struct S_2 : RegS<S_2> { ... };
...
struct S_n : RegS<S_n> { ... };
与n.m.的变体相比,差异在于我在这里使用了CRTP模式,而不是枚举实例化,这也是我想避免的事情。     

解决方法

        您可以使用
typeinfo
作为键,但这不是一个好主意。您不应该在程序中计算类型。让我用一个简单的例子来解释。 假设您有一个
Vehicle
类型及其后代
Car
Truck
Bike
。您可以为每个这些类调用一次函数。到目前为止,一切都很好。现在,出于完全不相关的原因,您需要处理SUV,RacingCars,GarbageTruck,Trikes,RedCars,ReddishCars和YellowishReddishWithGreenishTintCars。您对函数将被调用的次数的决定应与针对每种情况引入或不引入单独的类的决定完全正交。 因此,您只需要为每堆相似对象调用一次函数的目的就可以将Vehicles标记为与众不同或相似。一种实现方法是使用类模板和一堆类型参数(任何类型的参数)。
class ChangerOfInternalStateOfI
{
  public:
    ChangerOfInternalStateOfI (I* i) { 
      makeSomeChangesToTheInternalStateOfI(i); 
    }
};

template <int n>
class S_N : public S
{
  public:
    S_N() {
       static ChangerOfInternalStateOfI changer;
    }
};

typedef S_N<1> S_1;
typedef S_N<2> S_2;
您可以使用enum代替int或类型名,这并不重要。关键是您所有的ChangerOfInternalStateOfI都是不同的,因为它们属于不同的类,并且每个构造函数都将被调用一次。     ,        如果该方式具有静态数据成员n.m.提到的不符合目标, 在
I
中处理过包含类型的集合怎么样? 由于ѭ35本身并不比同类产品差,因此一个简单的包装器 以下代码中使用36。 如果必须多态地进行类型检查(通过基本类
S
), 需要运行时类型信息。 所以我使
changeStateOfI
成为
virtual
#include <typeinfo>
#include <set>
using namespace std;

struct type_info_ {
  type_info const *t;
  type_info_( type_info const* t ) : t( t ) {}
  bool operator<( type_info_ const& x ) const { return t->before( *x.t ); }
};

struct I {
  set< type_info_ > types;

  void f( type_info const& t,char const* s ) {
    if ( types.insert( type_info_( &t ) ).second ) { puts( s ); }
  }
};

struct S {
  virtual void changeStateOfI( I& i,char const* s ) {
    i.f( typeid( *this ),s );
  }
};

struct S_1 : S {};
struct S_2 : S {};

int main() {
  I i1,i2;
  S_1 s1a,s1b;
  S_2 s2a,s2b;
  s1a.changeStateOfI(i1,\"s1a i1\");
  s1b.changeStateOfI(i1,\"s1b i1\");
  s2a.changeStateOfI(i1,\"s2a i1\");
  s2b.changeStateOfI(i1,\"s2b i1\");
  s1a.changeStateOfI(i2,\"s1a i2\");
  s1b.changeStateOfI(i2,\"s1b i2\");
  s2a.changeStateOfI(i2,\"s2a i2\");
  s2b.changeStateOfI(i2,\"s2b i2\");
}
上面的代码分别是
s1a i1
s2a i1
s1a i2
s2a i2
在我的环境中     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-