如何在C++中的对象之间共享公共资源
how to share common resource amongst objects in c++
在 C++ 中,我经常 运行 遇到这个问题并且总是感到困惑。假设有多个级别的 classes。每个级别都在实例化 class ,它是下面的级别。例如。低于 level1 实例化 level2_a 和 b(在实际情况下还有更多)。
现在叶级对象需要执行一些操作。简单的例子,假设叶级对象需要将一些信息转储到状态控制台。所有叶级对象都需要这样做。在对象之间共享此“状态控制台”指针的最佳方式是什么(这些对象可能有 100 个)?
- 是否都需要存储指向它的指针?
- 或者将“状态控制台”指针传递给某个成员函数调用,然后它可以用来转储日志。
另一个这样的例子,他们都需要共享一个堆栈,当它们被销毁时,它们会在上面传递一些信息?如何在所有这些叶级对象之间共享堆栈指针
示例:
class level2_a
{
<properties here differ from level2_b>
public:
~level2_a()
{
// dump some info into a common stack here
}
void dump_change_to_value(int newval)
{
// need a console pointer here
// but can't be singleton because there's 1 per window
}
};
class level2_b
{
<properties here differ from level2_a>
public:
~level2_b()
{
// dump some info into a common stack here
}
void dump_change_to_value(int newval)
{
// need a console pointer here
// but can't be singleton because there's 1 per window
}
};
class level1
{
private:
level2_a* ml2_a;
level2_b* ml2_b;
public:
<func members..>
};
如何实现stack/console在level2_a和b
之间的共享
通常,我通过通常是单例的co-class在基础class中设置记录器。
我显然总是定义一些基本的记录器:
- 空记录器(不打印任何内容),
- 控制台记录器(标准输出/错误),
- 文件记录器(是否合并
stdout
/stderr
)。
很明显,事实上,它是相同的 class,但实例化了不同的文件句柄。内部单例实例存储在映射中,其中关键部分是传递给 getInstance
方法的值的元组。然后,一旦实例已知,每个 class 使用它的人都会将其存储在 shared_ptr
.
中
默认是在基础 class 中设置您的记录器,通过在创建新派生实例时将用作“默认记录器”的静态属性。但是每个实例也可以设置自己的“私有”记录器,用于调试目的...例如,您可以将“NullLogger”设置为基础class,并将“FileLogger”设置为您当前调试的派生class.
而且,显然,您的程序的其余部分仍然可以使用“SysLogger”在集中位置继续正常日志,例如 rsyslog
或类似的东西。
所有这些仅依赖于保存默认值的静态成员、真正使用的普通属性(在记录器 setter 的构造函数 and/or 中设置),以及明显的虚拟方法。
请注意,“默认”表示“记录器在实例化时连接”,因此更改默认记录器不会传播到所有子实例...除非您在访问记录器时不断使用三元运算符(使用类似于(mThisLogger?mThisLogger:sDefLogger)->log(...)
可以放在一个内联的私有继承函数中)。
好的部分是您不必在初始连接后关心记录器,如果需要它甚至会自动传播(只需要 mutexes/signals 更改它而不会弄乱一切)。但是您仍然可以更改特定实例的记录器,这样您就可以为该实例设置不同的详细级别,或者将日志发送到更方便的目的地(如干净的控制台) , 独立文件, ...) 而无需更改代码中的任何其他内容,如下所示:
#ifdef _DEBUG // or a "if (isDebug())" if you have such a function...
annoyingInstance->setLog(allLoggersNamespace::DebugLogger);
annoyingInstance->setLogLevel(Logger::FullTrace);
#endif
在 C++ 中,我经常 运行 遇到这个问题并且总是感到困惑。假设有多个级别的 classes。每个级别都在实例化 class ,它是下面的级别。例如。低于 level1 实例化 level2_a 和 b(在实际情况下还有更多)。 现在叶级对象需要执行一些操作。简单的例子,假设叶级对象需要将一些信息转储到状态控制台。所有叶级对象都需要这样做。在对象之间共享此“状态控制台”指针的最佳方式是什么(这些对象可能有 100 个)?
- 是否都需要存储指向它的指针?
- 或者将“状态控制台”指针传递给某个成员函数调用,然后它可以用来转储日志。
另一个这样的例子,他们都需要共享一个堆栈,当它们被销毁时,它们会在上面传递一些信息?如何在所有这些叶级对象之间共享堆栈指针
示例:
class level2_a
{
<properties here differ from level2_b>
public:
~level2_a()
{
// dump some info into a common stack here
}
void dump_change_to_value(int newval)
{
// need a console pointer here
// but can't be singleton because there's 1 per window
}
};
class level2_b
{
<properties here differ from level2_a>
public:
~level2_b()
{
// dump some info into a common stack here
}
void dump_change_to_value(int newval)
{
// need a console pointer here
// but can't be singleton because there's 1 per window
}
};
class level1
{
private:
level2_a* ml2_a;
level2_b* ml2_b;
public:
<func members..>
};
如何实现stack/console在level2_a和b
之间的共享通常,我通过通常是单例的co-class在基础class中设置记录器。
我显然总是定义一些基本的记录器:
- 空记录器(不打印任何内容),
- 控制台记录器(标准输出/错误),
- 文件记录器(是否合并
stdout
/stderr
)。
很明显,事实上,它是相同的 class,但实例化了不同的文件句柄。内部单例实例存储在映射中,其中关键部分是传递给 getInstance
方法的值的元组。然后,一旦实例已知,每个 class 使用它的人都会将其存储在 shared_ptr
.
默认是在基础 class 中设置您的记录器,通过在创建新派生实例时将用作“默认记录器”的静态属性。但是每个实例也可以设置自己的“私有”记录器,用于调试目的...例如,您可以将“NullLogger”设置为基础class,并将“FileLogger”设置为您当前调试的派生class.
而且,显然,您的程序的其余部分仍然可以使用“SysLogger”在集中位置继续正常日志,例如 rsyslog
或类似的东西。
所有这些仅依赖于保存默认值的静态成员、真正使用的普通属性(在记录器 setter 的构造函数 and/or 中设置),以及明显的虚拟方法。
请注意,“默认”表示“记录器在实例化时连接”,因此更改默认记录器不会传播到所有子实例...除非您在访问记录器时不断使用三元运算符(使用类似于(mThisLogger?mThisLogger:sDefLogger)->log(...)
可以放在一个内联的私有继承函数中)。
好的部分是您不必在初始连接后关心记录器,如果需要它甚至会自动传播(只需要 mutexes/signals 更改它而不会弄乱一切)。但是您仍然可以更改特定实例的记录器,这样您就可以为该实例设置不同的详细级别,或者将日志发送到更方便的目的地(如干净的控制台) , 独立文件, ...) 而无需更改代码中的任何其他内容,如下所示:
#ifdef _DEBUG // or a "if (isDebug())" if you have such a function...
annoyingInstance->setLog(allLoggersNamespace::DebugLogger);
annoyingInstance->setLogLevel(Logger::FullTrace);
#endif