需要有关在类之间共享变量的 OOP 设计的帮助,这些变量单独使用计时器运行
Need help about OOP-design for sharing variables between classes, which run with a timer indipendently
假设我有 2 个类 Fly 和 Bee,它们的方法(分别运行和循环)在不同的时间运行。
/* Fly */
using namespace boost::asio
using namespace boost::posix_time
class Fly {
...
deadline_timer timeout_fly_;
char text_fly_;
Fly::Fly( io_service &io): timeout_fly_(io, seconds(4) )
{
timeout_fly_.async_wait( boost::bind( &Fly::run, this ) );
}
Fly::run(void)
{
std::cout << "Running Fly forever" << std::endl;
timeout_fly_.expires_at( timeout_fly_.expires_at() + seconds(4)));
timeout_fly_.async_wait( boost::bind( &Fly::run, this ) );
}
和:
/* Bee */
class Bee {
...
deadline_timer timeout_bar_;
char text_bee_;
Bee::Bee(io_service &io): timeout_bee_(io, seconds(2) )
{
timeout_bee_.async_wait( boost::bind( &Bee::loop, this ) );
}
Bee::loop(void)
{
std::cout << "Running Bee forever" << std::endl;
timeout_bee_.expires_at( timeout_bee_.expires_at() + seconds(2) );
timeout_bee_.async_wait( boost::bind( &Bee::loop, this ) );
}
主要以以下方式开始:
/* main.cpp */
io_service io_service;
while(1) {
io_service.run();
}
现在我遇到了一个问题,我需要在两个类之间交换一些数据(例如 char 文本)。但是我坚持了下来,无法解决这个问题,因为我不知道该怎么做。
我正在考虑将一个类传递给另一个类作为参考:
using namespace boost::asio
using namespace boost::posix_time
class Fly {
...
deadline_timer timeout_fly_;
Bee bee_;
char text_fly_;
...
Fly::Fly(io_service &io, Bee &bee): timeout_fly_(io,seconds(4)), bee_(bee)
{
timeout_fly_.async_wait(boost::bind( &Fly::run, this));
}
Fly::run(void)
{
std::cout << "Running Fly forever" << std::endl;
text_fly_ = bee_->getTextInBee();
timeout_fly_.expires_at(timeout_fly_.expires_at() + seconds(4));
timeout_fly_.async_wait(boost::bind( &Fly::run, this));
}
但我不确定这是否是一个很好的OOP设计。此外,这将使我的程序复杂化。我想让它尽可能简单。另一种选择是创建 2 个不同的线程,让它们运行并使用互斥锁保存结果以同步两个线程。
如何在两个类之间交换一般数据?
您可以将这两个类之间共享的任何内容包装在一个单独的对象中,并让这两个类访问该对象的指针。如果 Fly 和 Bee 同时使用数据存在争用条件,则可以使用互斥锁。
在处理OOP设计的问题之前,稍微更正一下:
在构造函数中,通过引用原始对象传递bee
。 这将允许共享。 但是,您的bee_
成员是纯值。 因此,构造函数将复制原始对象。 因此,您不会处理共享值,而是处理其克隆,保持原始值不变。
使其成为引用或指针。
设计问题
你的设计需要改进:蜜蜂和苍蝇是两个独立的对象,独立存在。 通过在构造时提供指向另一个对象的指针,可以在两者之间创建与现实不符的依赖关系。 也就是说,没有蜜蜂,你就不能再创造一只苍蝇了。 如果您希望bee
对象访问fly
对象,您将如何做?!
另类
您可以使用这种倒数指针,但不应在构造时填充它。您应该更喜欢单独的二传手。由于两个对象的设置应该匹配,因此您需要在两个 setter 中实现倒数对象中的设置,以避免无休止的递归。 一个更干净的分配器可以使用一个朋友函数来设置一个相互链接。
class Fly {
Bee *bee_;
...
friend void peer(Bee&b, Fly&f);
};
class Bee {
Fly *fly_;
...
public:
...
friend void peer(Bee&b, Fly&f);
};
void peer(Bee&b, Fly&f) {
b.fly_ = &f;
f.bee_ = &b;
// this is simplified: in realit you'd check if each object if already
// bound, and if yes, it would first reset the binding of the old corresponding pointer.
}
在这两种情况下,您都可以通过从对等对象调用函数在对象之间传递数据,就像您所做的那样。完成getTextInBee()
另一种方法是使用第三个对象来表示消息/事件队列:
- 然后,
bee
和fly
可以使用此队列的观察者设计模式注册为观察者。 - 任何蜜蜂或苍蝇都可以向此队列发布消息
- 然后,队列将通知对象新消息。
这种设计比前一个设计稍微复杂一些,但它可以处理任意数量的对象(例如2只蜜蜂和5只苍蝇)。
这种实现可以通过使Fly
和Bee
都继承自相同的基类FlyingInsect
来进一步改进。
最后,我根据以下模式重写了代码。它由一个包装类组成,该包装类至少创建三个对象:
- 一类蜜蜂类型;
- 一类飞行类型;
- 一个类用于在两者之间交换数据;
在包装类中,我有如下所示的内容:
/* Wrapper class */
class Insect {
/* Class with methods and members for sharing data */
Data *exchange_data = new Data;
/* Generate Bee */
Bee bee;
/* Generate Fly */
Fly fly;
public:
Insect( boost::asio::io_service &io )
: bee(io, exchange_data), fly(io, exchange_data);
}
请注意,当调用公共shared_data类的构造函数时,该类现在在初始化列表中传递。该类是包装类的成员,一旦创建,必须传递给现在有点不同的两个类:
/* Fly */
using namespace boost::asio
using namespace boost::posix_time
class Fly {
...
deadline_timer timeout_fly_;
char text_fly_;
Data *shared_data;
Fly::Fly( io_service &io, Data *data): timeout_fly_(io, seconds(4)), shared_data(data)
{
timeout_fly_.async_wait( boost::bind( &Fly::run, this ) );
}
Fly::run(void)
{
std::cout << "Running Fly forever" << std::endl;
shared_data->setMember( "I write something here" );
timeout_fly_.expires_at( timeout_fly_.expires_at() + seconds(4)));
timeout_fly_.async_wait( boost::bind( &Fly::run, this ) );
}
和
/* Bee */
class Bee {
...
deadline_timer timeout_bar_;
char text_bee_;
Data *shared_data;
Bee::Bee(io_service &io, Data *data): timeout_bee_(io, seconds(2)), shared_data(data)
{
timeout_bee_.async_wait( boost::bind( &Bee::loop, this ) );
}
Bee::loop(void)
{
std::cout << "Running Bee forever" << std::endl;
shared_data->setMember( "I write something else here" );
timeout_bee_.expires_at( timeout_bee_.expires_at() + seconds(2) );
timeout_bee_.async_wait( boost::bind( &Bee::loop, this ) );
}
在这些类(Bee 和 Fly)中,您可以使用指针指向 Data 类型的同一对象。在这两种情况下,您都可以调用方法并设置或获取类 Data 的成员。由于这两个类都在线程内封装,因此您需要在 Data 中使用互斥锁,以避免两个线程同时写入相同的资源或变量。
我不会假装拥有可以开发的最好的设计。但它有效,尽管使用了指针和其他东西,但它仍然有效,并且非常容易理解并遵循这种设计背后的基本思想。
我希望它可以帮助其他有同样麻烦的人。
- 需要循环帮助以迭代方式添加到程序集中的总和变量
- 需要帮助定义循环控制变量(while loops)C++
- 如何使用类中的函数从 main 打印变量,帮助理解 OOP c++
- C++ getline(cin,变量)行为不端.网站上没有任何解决方案有帮助
- 需要帮助了解指针变量分配
- 需要有关 PATH 变量的帮助
- C++:帮助存储和显示输入文件变量
- C++ 帮助 - 在函数中使用 Ctime 为变量添加时间戳
- 在类中使用变量(C++帮助)
- 等待从获取锁的函数调用的帮助程序函数中的条件变量
- 需要帮助理解构造函数参数和静态变量
- 需要有关在类之间共享变量的 OOP 设计的帮助,这些变量单独使用计时器运行
- 面向对象C++帮助?出于某种原因,对象变量的输出返回数值数组位置而不是实际值
- 如何在 c++ 中将包含指针变量的对象写入和读取到文件中?帮助我使用以下代码
- 使用帮助程序函数 (c++) 定义运行时已知的全局 const 变量
- 统一的局部变量和帮助更正
- 如何在匿名命名空间中调用可变变量模板帮助器
- 需要帮助的变量转换和添加一个“”到现有的变量值
- 是否有一种工具可以帮助理解谁将特定的参数传递给函数,以及该变量最初是在哪里创建的(在C/ c++中)
- 需要帮助关于通过fstream保存变量,我需要使用向量