R
Ruben Lysens
Hi,
Consider the example below. A Device controls a number of Ports. I'd
like the Device to be in charge of creating/deleting Ports. I enforce
this by making the Ports constructor and destructor private and making
Device a friend of Port. In Device's destructor I'd like to use a
generic purge function to delete all Ports. Ofcourse that doesn't work
because the Port destructor is private for Purge.
So, where did I go wrong? I went for the private ctor/dtor + friend
approach to keep things as encapsulated as possible. I can make Port's
ctor/dtor public, but ideally I don't want clients to be able to create
Ports. Alternatively, I could duplicate purge's functionality inside the
Device destructor, but that's not my favourite kind of code reuse. How
do you fix this design?
Ruben.
#include <vector>
#include <iostream>
using namespace std;
/*From Bruce Eckel's Thinking in C++ Vol.2.
*Belongs in a separate purge.h file*/
template<class Seq> void purge(Seq& c) {
typename Seq::iterator i;
for(i = c.begin(); i != c.end(); ++i) {
delete *i;
*i = 0;
}
}
class Device {
public:
class Port {
public:
void doSomething() {
cout << "port " << id_ << " doing something." << endl;
};
private:
int id_;
Device& device_;
Port(int id, Device &device) : id_(id), device_(device) {}
~Port() {
cout << "destructing port" << endl;
}
friend class Device;
};
Device(int numPorts) {
for (int i=0; i<numPorts; i++) {
ports_.push_back(new Port(i, *this));
}
}
~Device() {
purge(ports_);
}
Port* getPort(int i) {
return ports_.at(i);
}
private:
vector<Port*> ports_;
};
int main() {
Device device(10);
return 0;
}
Consider the example below. A Device controls a number of Ports. I'd
like the Device to be in charge of creating/deleting Ports. I enforce
this by making the Ports constructor and destructor private and making
Device a friend of Port. In Device's destructor I'd like to use a
generic purge function to delete all Ports. Ofcourse that doesn't work
because the Port destructor is private for Purge.
So, where did I go wrong? I went for the private ctor/dtor + friend
approach to keep things as encapsulated as possible. I can make Port's
ctor/dtor public, but ideally I don't want clients to be able to create
Ports. Alternatively, I could duplicate purge's functionality inside the
Device destructor, but that's not my favourite kind of code reuse. How
do you fix this design?
Ruben.
#include <vector>
#include <iostream>
using namespace std;
/*From Bruce Eckel's Thinking in C++ Vol.2.
*Belongs in a separate purge.h file*/
template<class Seq> void purge(Seq& c) {
typename Seq::iterator i;
for(i = c.begin(); i != c.end(); ++i) {
delete *i;
*i = 0;
}
}
class Device {
public:
class Port {
public:
void doSomething() {
cout << "port " << id_ << " doing something." << endl;
};
private:
int id_;
Device& device_;
Port(int id, Device &device) : id_(id), device_(device) {}
~Port() {
cout << "destructing port" << endl;
}
friend class Device;
};
Device(int numPorts) {
for (int i=0; i<numPorts; i++) {
ports_.push_back(new Port(i, *this));
}
}
~Device() {
purge(ports_);
}
Port* getPort(int i) {
return ports_.at(i);
}
private:
vector<Port*> ports_;
};
int main() {
Device device(10);
return 0;
}