I have the following situation: a class NoEntry contains data which can be inspected by the outside world, but the outside world is not allowed, in any way, to create those objects. Such a class looks like this:
#ifndef INCLUDED_NOENTRY_
#define INCLUDED_NOENTRY_
#include <string>
class NoEntry
{
std::string d_name;
size_t d_area = 0;
size_t d_date = 0;
public:
std::string const &name() const;
size_t area() const;
size_t date() const;
private:
NoEntry(NoEntry const &other) = default;
NoEntry() = default;
NoEntry(std::string const &name, size_t area, size_t date);
};
#endif
Using NoEntry objects is a privilege of certain classes, declared as friends of NoEntry. So the class contains friend declarations:
#ifndef INCLUDED_NOENTRY_
#define INCLUDED_NOENTRY_
#include <string>
class NoEntry
{
friend class PrivilegedOne;
friend class PrivilegedTwo;
std::string d_name;
size_t d_area = 0;
size_t d_date = 0;
public:
std::string const &name() const;
size_t area() const;
size_t date() const;
private:
NoEntry(NoEntry const &other) = default;
NoEntry() = default;
NoEntry(std::string const &name, size_t area, size_t date);
};
#endif
I have designed the following PrivilegedOne interface:
#ifndef INCLUDED_PRIVILEGEDONE_
#define INCLUDED_PRIVILEGEDONE_
#include <iosfwd>
#include <vector>
#include "../noentry/noentry.h"
class PrivilegedOne
{
std::vector<NoEntry> d_noEntry;
public:
PrivilegedOne(std::string const &fname);
private:
NoEntry nextEntry(std::istream &in); // empty name: all were read
};
#endif
Its member nextEntry is a simple one: it reads the data from file, and returns a NoEntry object.
//#define XERR
#include "privilegedone.ih"
NoEntry PrivilegedOne::nextEntry(istream &in)
{
NoEntry ret;
in >> ret.d_name >> ret.d_area >> ret.d_date;
if (not in) // no more NoEntries: ensure
ret.d_name.clear(); // that d_name is empty
return ret;
}
PrvilegedOne's constructor must read all the NoEntry objects and must store them in d_noEntry. Here is its original implementation:
//#define XERR
#include "privilegedone.ih"
PrivilegedOne::PrivilegedOne(string const &fname)
{
ifstream in{ fname };
while (true)
{
NoEntry next = nextEntry(in);
if (next.name().empty())
break;
d_noEntry.push_back(next); // Not working
}
}
The "Not working" comment is the line that is causing all the problems.
Why doesn't the statement do its job? Without modifying anything in the class NoEntry, but merely concentrating on PrivilegedOne: what must be done to allow objects of this class to store NoEntry objects in its d_noEntry vector?
I think I should redesign the definition of d_noEntry. And then I'll only have to modify the line with the "not working" comment.
But I am not sure how.