How to load content of a const variable from a file? - c++

What is the method to save and retrieve contents (to/from a disk file) of an object who has const member variables?
Or more specifically, const members demand an initialization at the creation time of the object. So, the retrieval of the content has to happen before the initializers (before { } of the constructor). If we are not minding the encapsulation, we can retrieve and create the object with parameters. How to do everything by keeping the data-hiding?
Compiler: C++ 14 and maybe beyond.
Instantiation of the object, filling the content and storing for next context.
{ //CODE BLOCK 1 : making of content and saving to a diskfile
Abcd abcd(65535,256,25);
//some operations on abcd
//save to disk
QFile abcdFile("abcd.lion");
abcdFile.open(QFile::WriteOnly);
abcd.serialize(abcdFile);
abcdFile.close();
}
using same object after taking from file.
{ //CODE BLOCK 2 : loading from file and continue in another context
QFile abcdFile("abcd.lion");
abcdFile.open(QFile::ReadOnly);
Abcd abcdNew(abcdFile);
abcdFile.close();
if(!abcdNew.isHealthy())
printf("abcd from hdd is NOT Healthy :(\n");
else
{
//doTheJob(abcdNew);
}
}
The class.
#include <QFile>
class Abcd
{
const bool _healthy;//true if properly initialized
//IMPORTANT: _healthy has to be the first member in the class.
//this is to execute its initializer list first
protected:
const long _rX;
const long _rY;
long _count;
public:
Abcd(const long refX,
const long refY,
const long count) :
_healthy(true),
_rX(refX), _rY(refY),
_count(count)
{
}
Abcd(QFile &src) :
_healthy(deserialize(src)),
//Hack. Actually the initialization happened by this statement.
//just keeping the below statements for the sake of syntactical correctness. :(
_rX(_rX), _rY(_rY)
//,_count(count)
{
}
virtual
~Abcd()
{
}
inline
bool isHealthy()
{
return _healthy;
}
bool serialize(QFile &dest)
{
if(dest.write((char *)&_rY,sizeof(_rY))!=sizeof(_rY)) return false;
if(dest.write((char *)&_rX,sizeof(_rX))!=sizeof(_rX)) return false;
if(dest.write((char *)&_count,sizeof(_count))!=sizeof(_count)) return false;
return true;
}
private:
bool deserialize(QFile &src)
{
if(src.read((char *)&_rY,sizeof(_rY))!=sizeof(_rY)) return false;
if(src.read((char *)&_rX,sizeof(_rX))!=sizeof(_rX)) return false;
if(src.read((char *)&_count,sizeof(_count))!=sizeof(_count)) return false;
return true;
}
};
Please suggest a better method. For this, I have introduced a ‘healthy’ status member as the first member in the declaration of the class. Also in deserialization, I am fooling the compiler by casting the const variable to char * pointer.

My suggestion will be to use a static member function of the class to retrieve the contents of the file from disk and construct an object after the contents have been retrieved successfully.
Instead of:
Abcd(QFile &src) :
Use
static Abcd deserialize(QFile& src);
and implement it as:
Abcd Abcd::deserialize(QFile& src)
{
long rX;
long rY;
long count;
if(src.read((char *)&rY, sizeof(rY)) != sizeof(rY)) throw false;
if(src.read((char *)&rX, sizeof(rX)) != sizeof(rX)) throw false;
if(src.read((char *)&count, sizeof(count)) != sizeof(count)) throw false;
return Abcd(rX, rY, count):
}
PS It's strange that you save _rY first and then _rX. There is nothing wrong, it's just strange.

My suggestion is to split up the logic of Abcd and serialization/deserialization into two classes.
Benefits:
no field _healthy as object is always valid by design.
class Abcd does only one job. Is free from any logic of storing (Single responsibility)
Few hints:
RVO is mandatory since c++ 17
const fields just make the object not copy/move assignable (unable to use with containers etc.). Simply properly use const correctness to ensure immutability.
do not inherit implementation, only interfaces: Abcd is final, no virtual methods - better performance.
follow the Cpp Core Guidelines
class Abcd final
{
public:
Abcd(const long refX, const long refY, const long count)
: _rX(refX)
, _rY(refY)
, _count(count)
{
}
long GetRX() const
{
return _rX;
}
long GetRY() const
{
return _rY;
}
long GetCount() const
{
return _count;
}
protected:
long _rX;
long _rY;
long _count;
};
#include <boost/optional.hpp>
#include <QFile>
template <typename T>
using Opt = boost::optional<T>; // or equivalent
// Choose better name for Serializer or even split it up
class AbcdSerializer final
{
public:
AbcdSerializer(QFile& file)
: _file(file)
{
}
// You may also throw an exception instead of returning optional
Opt<Abcd> TryDeserializeAbcd()
{
long rX;
long rY;
long count;
if (ReadValue(rY) && ReadValue(rX) && ReadValue(count))
{
return Abcd(rX, rY, count);
}
return {};
}
bool SerializeAbcd(const Abcd& abcd)
{
return WriteValue(abcd.GetRY()) && WriteValue(abcd.GetRX()) && WriteValue(abcd.GetCount());
}
private:
template <typename T>
bool ReadValue(T& value)
{
constexpr auto ValueSize = sizeof(value);
return _file.read(reinterpret_cast<char*>(&value), ValueSize) != ValueSize;
}
template <typename T>
bool WriteValue(const T& value)
{
constexpr auto ValueSize = sizeof(value);
return _file.write(reinterpret_cast<const char*>(&value), ValueSize) != ValueSize;
}
QFile& _file;
};

Related

How do predicate and/or predicator data members and/or member functions work in C++? What does (elem.*predicator)() do in the following snippet?

I have the following snippet of code that seems to be making use of predicates but I am unable to figure out what (elem.*predicator)() does. I tried looking for some easier to understand documentation regarding the same on the web as well as SO (closest thing I found was this) but couldn't find anything that could help me.
The code:
using TimePoint = std::chrono::time_point<std::chrono::system_clock>;
The struct OperationPointInfo is as follows:
struct OperationPointInfo {
// The shelf in this operation point. -1 for empty.
int shelf_id;
bool scheduled_to_change;
// The time point the shelf was moved into the operation point, in the format of seconds since epoch.
TimePoint start_time;
// Index for this operation point.
int index;
OperationPointInfo() {
OperationPointInfo(-1);
}
OperationPointInfo(int index) : index(index) {
shelf_id = -1;
scheduled_to_change = false;
}
bool CapableForMoveOut() const {
return shelf_id >= 0 && !scheduled_to_change;
};
bool CapableForMoveIn() const {
return shelf_id < 0 && !scheduled_to_change;
};
};
The function which has got me baffled is this one:
template<class T>
std::optional<T> ReserviorSamplingOperationPoint(const vector<T> &array, bool (T::*predicator)(void) const) {
T selected;
bool found = false;
int counter = 1;
for (const auto &elem : array) {
if ((elem.*predicator)()) {
selected = elem;
found = true;
counter++;
}
}
if (found) {
return selected;
} else {
return nullopt;
}
}
Where the above function is being called:
void GenSpToOpMissions() {
std::vector<OperationPointInfo> operation_point_info_;
auto to_or_empty = ReserviorSamplingOperationPoint(operation_point_info_, &OperationPointInfo::CapableForMoveIn);
OperationPointInfo to = to_or_empty.value();
}
.* and ->* are the pointer-to-member operators.
Those are pointers that can store which method of a class to call.
See [expr.mptr.oper] in the standard or questions like Calling C++ class methods via a function pointer.

Preventing assignment by subscript operator by not returning references causes runtime crash

I'm doing this:
template<typename T> class var_accessor {
public:
std::set<std::shared_ptr<T>> varset;
std::map<std::string,std::shared_ptr<T>> vars_by_name;
std::map<uint32,std::shared_ptr<T>> vars_by_id;
std::shared_ptr<T> operator[](const uint32& index) { return vars_by_id[index]; }
std::shared_ptr<T> operator[](const std::string& index) { return vars_by_name[index]; }
bool is_in_set(std::shared_ptr<T> what) { auto it = varset.find(what); if (it == varset.end()) return false; return true; }
bool is_in_set(uint32 what) { auto it = vars_by_id.find(what); if (it == vars_by_id.end()) return false; return true; }
bool is_in_set(std::string& what) { auto it = vars_by_name.find(what); if (it == vars_by_name.end()) return false; return true; }
bool place(std::shared_ptr<T> what, const uint32 whatid, const std::string& whatstring) {
if (is_in_set(what)) return false;
varset.emplace(what);
vars_by_name.emplace(whatstring,what);
vars_by_id.emplace(whatid,what);
return true;
}
};
Then...
class whatever {
std::string name;
std::function<int32()> exec;
};
And:
class foo {
public:
var_accessor<whatever> stuff;
};
This works:
std::shared_ptr<whatever> thing(new whatever);
thing->name = "Anne";
thing->exec = []() { return 1; }
foo person;
person.stuff.emplace(thing, 1, thing->name);
Getting the name crashes it:
std::cout << person.stuff[1]->name;
But if I change the operator[]'s to return references, it works fine.
I don't want to be able to accidentally add new elements without adding to all 3 structures, so that's why I made
std::shared_ptr<T> operator[]
instead of
std::shared_ptr<T>& operator[]
Is there any way to prevent assignment by subscript but keep the subscript operator working?
To be clear I want to be able to keep doing
std::cout << person.stuff[4];
But NOT be able to do
std::shared_ptr<whatever> bob(new whatever);
bob->name = "bob";
person.stuff[2] = bob;
The error is a EXC_BAD_ACCESS inside the std::string class madness
Everything I read says simply "don't return references if you want to prevent assignment" but it also prevents using it for me.
Yes I know some things should be made private but I just want to get it working first.
Using Clang/LLVM in XCode 5.1
Thanks!
You should return a const reference. See this question
A const reference means the caller is not allowed to change the value, only look at it. So assignment will be a compile-time error. But using it will work (and be efficient).

Duplicate instantiation of singleton

Working on a large project concerning C++ and Matlab cooperation through Mex we are currently struggling with one of our singletons.
The class is being generated through macros during preprocessing so it may seem a bit odd.
class AdditionalOperation {
private:
const std::string* val;
typedef std::map<std::string, const std::string*> StringMap;
static StringMap& getStringToPointerMap()
{
static StringMap map;
return map;
}
static boost::mutex& getMutex()
{
static boost::mutex mutex;
return mutex;
}
AdditionalOperation(const std::string* s)
:val(s)
{}
private:
static std::string* none_string()
{
static std::string s = "none";
static int count = 0;
boost::mutex::scoped_lock lock(getMutex());
if(count++ == 0) {
getStringToPointerMap().insert(std::make_pair(s,&s));
}
return &s;
}
public:
static AdditionalOperation none()
{
return AdditionalOperation(none_string());
}
private:
static std::string* norm_string()
{
static std::string s = "norm";
static int count = 0;
boost::mutex::scoped_lock lock(getMutex());
if(count++ == 0) {
getStringToPointerMap().insert(std::make_pair(s,&s));
}
return &s;
}
public:
static AdditionalOperation norm()
{
return AdditionalOperation(norm_string());
}
private:
static void prepare()
{
none();
norm();
}
public:
static AdditionalOperation fromString(std::string s)
{
static int count = 0;
if(count++ == 0)
prepare();
boost::mutex::scoped_lock lock(getMutex());
StringMap& map = getStringToPointerMap();
StringMap::iterator location = map.find(s);
if(location == map.end()) {
throw UnknownEnumValue(s);
}
return AdditionalOperation(location->second);
}
std::string toString() const
{
return *val;
}
bool operator==(const AdditionalOperation& other) const
{
return val == other.val;
}
bool operator!=(const AdditionalOperation& other) const
{
return !(*this == other);
}
};
All this code is generated from this line (through macros as stated above):
DECLARE_SENUM(AdditionalOperation, none, norm);
Which is a nice interface that we'd like to keep on using.
We want to use this class as a replacement for enumerations because we need to translate them from string and to a string. In this class we have 2 'enumeration' members namely norm and none.
Now we have added some logging and have determined that the insert operation inside the none_string and norm_string function is being called twice even though our counter should prevent this.
Some things we have tried :
We are working with a dynamic library but using -rdynamic did not help.
When we print the address of the static variables we can clearly see that they differ.
This class is situated within a dynamic library which in turn is linked with a mex file. This mex file is being dynamically loaded by another mex file through dlopen.
We were thinking that perhaps multiple instances of this class are declared and active because of the dynamic library. But we also use other kind of singletons that have not shown any sign of problems.
I hope it was clear enough, additional information or clarification can always be provided!
Thanks in advance!
You are, clearly, overcomplicating the problem.
std::string const& to_string(MyEnum e) {
static std::string const First = "First";
static std::string const Second = "Second";
switch(e) {
case MyEnum::First: return First;
case MyEnum::Second: return Second;
}
throw std::runtime_error("Unknown enum value");
}
would work as well, if not better and faster.

How can I create a switch for class members?

Say I have a class with a couple of data members, and I want a class method that returns one, and the next time it is called returns the value of the other. Something like:
class MyClass
{
public:
MyClass():switch(0){};
int get();
private:
int intA, intB;
int sw;
};
int MyClass::get()
{
if ( (++sw)%2 )
return intA;
else
return intB;
}
What would a more elegant way of doing it be? I don't like the if...else statement very much. It's fine for something like return, but if I'm actually using more complex operations, I end up duplicating a ton of code. Or having to create a second method within each method that is called after I resolve what element I'm pointing to.
What I'd prefer to do, ideally, is to use some form of pointer, so I can do
class MyClass
{
public:
MyClass():switch(&intA){};
int get();
void toggleSwitch();
private:
int intA, intB;
int * sw;
};
int MyClass::get()
{
return *sw;
}
void MyClass::toggleSwitch()
{
if ( sw == &intA )
sw = &intB;
else
sw = &intA;
}
Or something to that effect. I could call toggleSwitch(), and have my class operate on either one or the other value easily.
I still don't like it though. I prefer to avoid if's when possible, and I shouldn't need one in this case. This use of a naked pointer should be pretty safe, but I was thinking I could have something like std::unique_ptr holding each element and then std::swap them. But then the pointers would own the elements, and they'd be dynamic memory instead.
So is there a better way to do it?
Well, switch is a keyword, but I'll roll with it. How about an array of pointers?
int *fields[] = {&intA, &intB};
int MyClass::get()
{
return *fields[++switch % 2];
}
This would expand nicely if you could have additional variables later.
Or maybe:
int MyClass::get()
{
return *fields[switch = 1 - switch];
}
If you return a reference then you could use get() internally.
int &MyClass::get()
{
return *fields[switch = 1 - switch];
}
I would encapsulate the concept of a toggling value:
template<typename T>
class Toggleable {
T first;
T second;
T* current;
T* other;
public:
Toggleable(const T& first, const T& second)
: first(first),
second(second),
current(&first),
other(&second) {
}
bool toggle() {
std::swap(current, other);
}
const T& get() const {
return *current;
}
}
Then use as:
class MyClass
{
Toggleable<int> value;
public:
MyClass()
: value(42, 1729)
{
}
const int& get() {
value.toggle();
return value.get();
}
};

How to add elements of an array to a set

I have defined the classes 'Outcome' and 'Bin'.
I am trying to pass an array of type Outcome to a Bin Constructor, in order to add each element of that array to a set of 'Outcome's that is a member property of the Bin Class.
//Bin.h
class Bin {
private:
std::set<Outcome> outcomeset;
public:
Bin();
Bin(Outcome Outcs[], int numberofelements);
Bin(std::set<Outcome> Outcs);
void add(Outcome Outc);
std::string read();
};
//In Bin.cpp
Bin::Bin(Outcome outcs[], int numberofelements) {
int i;
for (i=0;i<(numberofelements-1);i++) {
outcomeset.insert(outcs[i]); //When this LIne is commented out, no compile errors!
}
}
This results in a whole mess of errors in VS2010 that link back to library files. I have been unable to find anything online or in my "The Big C++" textbook. Is this a completely wrong implementation of this sort of functionality? Or am I missing something rather basic?
For the curious I am implementing this as part of the 'Roulette' Problem from this free textbook http://www.itmaybeahack.com/homepage/books/oodesign.html
Thanks for your help!
EDIT: I have added the (rather lengthy) error text to a pastebin, here: http://pastebin.com/cqe0KF3K
EDIT2: I have implemented the == != and < operators for the outcome class, and the same line still does not compile. Here are the implementations
//Outcome.cpp
bool Outcome::operator==(Outcome compoutc) {
if (mEqual(compoutc) == true) {
return true;
}
else {
return false;
}
}
bool Outcome::operator!=(Outcome compoutc) {
if (mEqual(compoutc) == false) {
return true;
}
else {
return false;
}
}
bool Outcome::operator<(Outcome compoutc) {
if (odds < compoutc.odds) {
return true;
}
else {
return false;
}
}
EDIT3: Implemented the comparison operator with the de-referenced parameter and const tags and now it compiles!
You need to define an operator< for the class being inserted into the set.
Also note that instead of an explicit loop, you're probably better off using a pair of "iterators" (pointers, in this case) and actually initializing the set:
#include <set>
#include <string>
class Outcome {
int val;
public:
bool operator<(Outcome const &other) const {
return val < other.val;
}
Outcome(int v = 0) : val(v) {}
};
class Bin {
private:
std::set<Outcome> outcomeset;
public:
Bin();
// Actually initialize the set:
Bin(Outcome Outcs[], int n) : outcomeset(Outcs, Outcs+n) {}
Bin(std::set<Outcome> Outcs);
void add(Outcome Outc);
std::string read();
};
int main() {
// Create an array of Outcomes
Outcome outcomes[] = {Outcome(0), Outcome(1) };
// use them to initialize the bin:
Bin b((outcomes),2);
return 0;
}