繁体   English   中英

为什么此C ++ 0x程序生成意外的输出?

[英]Why does this C++0x program generates unexpected output?

该程序:

test_header.hpp

#include <boost/signal.hpp>
#include <utility>

class Sensor;

class Recorder : public ::boost::signals::trackable {
 public:
   explicit Recorder(int id) : id_(id) {}

   // Cannot be copied
   Recorder(const Recorder &) = delete;
   Recorder &operator =(const Recorder &) = delete;

   // But can be moved so it can be stored in a vector.
   // There's a proposal for having a compiler generated default for this that would be
   // very convenient.
   Recorder(Recorder &&b) : id_(b.id_) {
      b.id_ = -1;
   }
   Recorder &operator =(Recorder &&b) {
      id_ = b.id_;
      b.id_ = -1;
      return *this;
   }

   void recordSensor(const Sensor &s);
   void addSensor(Sensor &s);

 private:
   int id_;
   char space_[1312];
};

class Sensor {
 public:
   typedef ::boost::signal<void (const Sensor &)> sigtype_t;

   explicit Sensor(int id) : val_(0), id_(id) { }

   void notify(const sigtype_t::slot_type &slot) { signal_.connect(slot); }
   void updateSensor(double newval) { val_ = newval; signal_(*this); }
   double getValue() const { return val_; }
   int getId() const { return id_; }

 private:
   sigtype_t signal_;
   double val_;
   const int id_;
};

test_body.cpp

#include "test_header.hpp"
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>

void Recorder::addSensor(Sensor &s)
{
   ::std::cout << "Recorder #" << id_
               << " now recording Sensor #" << s.getId() << '\n';
   ::std::cout.flush();
   s.notify(::boost::bind(&Recorder::recordSensor, this, _1));
}

void Recorder::recordSensor(const Sensor &s)
{
   ::std::cout << "Recorder #" << id_ << " - new value for sensor named Sensor #"
               << s.getId() << ": " << s.getValue() << '\n';
   ::std::cout.flush();
}


int main(int argc, const char *argv[])
{
   using ::boost::shared_ptr;
   using ::std::vector;
   vector<Recorder> recorders;
   vector<shared_ptr<Sensor> > sensors;
   double val = 0.1;
   static const unsigned int recorder_every = 4;
   static const unsigned int sensor_every = 2;

   for (unsigned int i = 0; i < 9; ++i) {
      if (i % recorder_every == 0) {
         recorders.push_back(Recorder(i / recorder_every));
      }
      if (i % sensor_every == 0) {
         shared_ptr<Sensor> sp(new Sensor(i / sensor_every));
         sensors.push_back(sp);
         for (auto r = recorders.begin(); r != recorders.end(); ++r) {
            r->addSensor(*sp);
         }
      }
      for (auto s = sensors.begin(); s != sensors.end(); ++s, val *= 1.001) {
         (*s)->updateSensor(val);
      }
   }
}

我得到以下输出:

Recorder #0 now recording Sensor #0
Recorder #0 - new value for sensor named Sensor #0: 0.1
Recorder #0 - new value for sensor named Sensor #0: 0.1001
Recorder #0 now recording Sensor #1
Recorder #0 - new value for sensor named Sensor #0: 0.1002
Recorder #0 - new value for sensor named Sensor #1: 0.1003
Recorder #0 - new value for sensor named Sensor #0: 0.100401
Recorder #0 - new value for sensor named Sensor #1: 0.100501
Recorder #0 now recording Sensor #2
Recorder #1 now recording Sensor #2
Recorder #0 - new value for sensor named Sensor #2: 0.100803
Recorder #1 - new value for sensor named Sensor #2: 0.100803
Recorder #0 - new value for sensor named Sensor #2: 0.101106
Recorder #1 - new value for sensor named Sensor #2: 0.101106
Recorder #0 now recording Sensor #3
Recorder #1 now recording Sensor #3
Recorder #0 - new value for sensor named Sensor #2: 0.101409
Recorder #1 - new value for sensor named Sensor #2: 0.101409
Recorder #0 - new value for sensor named Sensor #3: 0.101511
Recorder #1 - new value for sensor named Sensor #3: 0.101511
Recorder #0 - new value for sensor named Sensor #2: 0.101815
Recorder #1 - new value for sensor named Sensor #2: 0.101815
Recorder #0 - new value for sensor named Sensor #3: 0.101917
Recorder #1 - new value for sensor named Sensor #3: 0.101917
Recorder #0 now recording Sensor #4
Recorder #1 now recording Sensor #4
Recorder #2 now recording Sensor #4
Recorder #0 - new value for sensor named Sensor #4: 0.102428
Recorder #1 - new value for sensor named Sensor #4: 0.102428
Recorder #2 - new value for sensor named Sensor #4: 0.102428

我有点困惑。 当我添加一个记录器时,似乎所有旧的传感器都被遗忘了。

记录器可以在内存中移动,因为您在创建矢量时会添加它们,但是在执行此操作时会绑定到它们以发出信号。

给记录器一个指向传感器矢量的索引,而不是指向该传感器的指针。 只要您不删除传感器,就可以正常工作。

Ergosys已经描述了问题的原因。 解决方案缺少的是:在绑定信号之前,请确保已完成将所有记录器和传感器添加到矢量中。 这样,他们的地址将完成更改。

这是主循环的修订版:

for (unsigned int i = 0; i < 9; ++i) {
   if (i % recorder_every == 0) {
      recorders.push_back(Recorder(i / recorder_every));
   }
   if (i % sensor_every == 0) {
      shared_ptr<Sensor> sp(new Sensor(i / sensor_every));
      sensors.push_back(sp);
   }
}
for (unsigned int i = 0; i < 9; ++i) {
   if (i % sensor_every == 0) {
      for (auto r = recorders.begin(); r != recorders.end(); ++r) {
         shared_ptr<Sensor> sp = sensors[i / sensor_every];
         r->addSensor(*sp);
      }
   }
   for (auto s = sensors.begin(); s != sensors.end(); ++s, val *= 1.001) {
      (*s)->updateSensor(val);
   }
}

您是否尝试过使用直数组而不是:: std :: vector? 我知道:: std :: vector是一种时尚的东西,但它实际上不是向量(更像是一个半列表半数组)。

暂无
暂无

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

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