Re: References
Andrea Crotti <andrea.crotti.0@gmail.com> wrote in
news:m1zkte9gfo.fsf@ip1-201.halifax.rwth-aachen.de:
Paavo Helde <myfirstname@osa.pri.ee> writes:
In your example Packer was a member of Packet. If there are many such
members then you have to update/notify them all in Packet::setX().
If each Packet has to take some action if x changes, then somebody
will have to tell it that x has changed, right? The simplest way is
to just call some function on each Packet. If they are all similar it
might make sense to derive them all from a common abstract virtual
base class and store a container of base class pointers. In this case
the notification function would loop over the container and call a
virtual function on each object.
- which would then make the right thing depending on the actual type
of
the object.
Ah that's interesting, but I didn't really get how to do in practice.
I mean, how do I create a container containing objects of different
type and loop over it?
#include <iostream>
#include <cmath>
#include <vector>
// use a smartpointer for automatic lifetime management.
// a raw pointer would work, but requires more care
#include <boost/smart_ptr.hpp>
class Packet;
class PackerBase {
public:
virtual void NotifyPacketChanged(Packet& p)=0;
virtual ~PackerBase() {}
};
typedef boost::shared_ptr<PackerBase> PackerPtr;
class Packet {
private:
int x_;
std::vector<PackerPtr> packers_;
private:
void NotifyPackers() {
for (size_t i=0; i<packers_.size(); ++i) {
packers_[i]->NotifyPacketChanged(*this);
}
}
public:
void setX(int x) {
x_ = x;
NotifyPackers();
}
Packet(int x) : x_(x) {}
void AddPacker(PackerPtr p) {
packers_.push_back(p);
p->NotifyPacketChanged(*this);
}
int GetX() const {return x_;}
};
class Packer1: public PackerBase {
private:
int y_;
private:
virtual void NotifyPacketChanged(Packet& p) {
y_ = 2*p.GetX();
std::cout << "Packer1 set to: " << y_ << "\n";
}
public:
Packer1(): y_(0) {}
};
class Packer2: public PackerBase {
private:
double z_;
private:
virtual void NotifyPacketChanged(Packet& p) {
z_ = std::sqrt(double(p.GetX()));
std::cout << "Packer2 set to: " << z_ << "\n";
}
public:
Packer2(): z_(0) {}
};
int main() {
Packet p1(10);
p1.AddPacker(PackerPtr(new Packer1()));
p1.AddPacker(PackerPtr(new Packer2()));
std::cout << p1.GetX() << std::endl;
p1.setX(3);
std::cout << p1.GetX() << std::endl;
return 0;
}
Output:
Packer1 set to: 20
Packer2 set to: 3.16228
10
Packer1 set to: 6
Packer2 set to: 1.73205
3