Insert an inherited instance to a instance of the same class - c++

I have a simple filesystem containing either a file or a directory. I have created an abstract class as a parent of both of these classes + two functions Size() and Change() as can be seen here:
class AbstractParent {
public:
explicit AbstractParent (const string & name = "", const unsigned int size = 0) : cString(name), cSize(size) {};
virtual ~AbstractParent() = default;
virtual unsigned int Size() const = 0;
unique_ptr<AbstractParent> Clone() const {
unique_ptr<AbstractParent> other(this->deepClone());
return other;
}
protected:
string cString;
unsigned int cSize;
//virtual copy constructor
virtual AbstractParent * deepClone() const = 0;
};
class CFile : public AbstractParent
{
public:
// constructor
explicit CFile (const string & hash, const unsigned int size) : AbstractParent(hash,size) {};
// Size
unsigned int Size() const override{
return cSize;
}
// Change
CFile & Change (const string & newHash, const unsigned int newSize) {
cString = newHash;
cSize = newSize;
return *this;
}
//virtual copy constructor
CFile * deepClone () const override{
return new CFile(*this);
}
};
class CDirectory : public AbstractParent
{
public:
// constructor
explicit CDirectory () {
systemMap = new map<string, unique_ptr<IFileSystem>>; //valgrind reports a leak here
};
// Size
unsigned int Size () const override {
return cSize;
}
// Change
CDirectory & Change (const string & FSName,const IFileSystem & file) {
systemMap->insert(make_pair(FSName, file.Clone()));
return *this;
}
//virtual copy
CDirectory * deepClone () const override {
return new CDirectory(*this);
}
private:
map<string, unique_ptr<IFileSystem>> * systemMap;
};
I have a problem with insering a directory into another directory. I would like to use a map for the directory, where the key is the name of the file/directory and its value is a pointer to the instance of it.
Here I have attempted to make it function with a virtual copy constructor and while it does compile, it does not work properly.
Valgrind is reporting lost memory where I allocate new map.
code in main to test out my implementation:
int main ()
{
CDirectory root;
stringstream sout;
root.Change("file.txt", CFile("jhwadkhawkdhajwdhawhdaw=", 1623))
.Change("folder", CDirectory()
.Change("fileA.txt", CFile("", 0).Change("skjdajdakljdljadkjwaljdlaw=", 1713))
.Change("fileB.txt", CFile("kadwjkwajdwhoiwhduqwdqwuhd=", 71313))
.Change("fileC.txt", CFile("aihdqhdqudqdiuwqhdquwdqhdi=", 8193))
);
return 0;
}
While debugging, everything gets inserted into the map of root as intended.
Only problem that remains is the memory of the map is lost.
Where should I free this memory, if it does not get freed implicitly?

Related

Strange "No instance of constructor matches the argument list" error (Solved)

Edit: I had copied the base template for the statisticscompiler class from another solution, and it seems I somehow had ended up editing the original one while including the new one (that hadn't been edited yet) which is what led to the errors. So a tale of caution against copy pasting code into another file with the same name.
I will just post the header files because I think that's what matters here, let me know if otherwise and I can post the cpp. I have one base class that collects statistics from a process, with two derived classes and then a class that let's me use several statistics classes at once
Statistics.h
#pragma once
#define STATISTIC_H
#include <vector>
#include "Arrays.h"
class Statistics
{
public:
Statistics() {}
virtual void DumpOnePath(MJArray results) = 0;
virtual std::vector<std::vector<double>> GetResultsSoFar() const = 0;
virtual Statistics* clone() const = 0;
virtual ~Statistics() {}
private:
};
class StatisticsMean : public Statistics
{
public:
StatisticsMean();
virtual void DumpOnePath(MJArray results) ;
virtual std::vector<std::vector<double>> GetResultsSoFar() const ;
virtual Statistics* clone() const;
private:
MJArray RunningSums;
unsigned long PathsDone;
};
class StatisticsQuantiles : public Statistics
{
public:
StatisticsQuantiles(double p_lower_, double p_upper_);
virtual void DumpOnePath(MJArray results);
virtual std::vector<std::vector<double>> GetResultsSoFar() const;
virtual Statistics* clone() const;
private:
std::vector<MJArray> RunningResults;
unsigned long PathsDone;
double p_lower;
double p_upper;
};
StatisticsCompiler.h
#pragma once
#define STATISTICS_COMPILER_H
#include "statistics.h"
#include "wrapper.h"
class StatisticsCompiler : public Statistics
{
public:
StatisticsCompiler(const std::vector <Wrapper<Statistics>>& Inner_);
virtual Statistics* clone() const;
virtual void DumpOnePath(MJArray results);
virtual std::vector<std::vector<double>> GetResultsSoFar() const;
private:
std::vector <Wrapper<Statistics>> Inner;
};
And in my main class I'm trying to do this:
StatisticsMean meanGatherer;
StatisticsQuantiles quantileGatherer(p_lower, p_upper);
vector<Wrapper<Statistics>> gathererArray{ meanGatherer, quantileGatherer};
StatisticsCompiler meanAndQuantileGatherer(gathererArray);
Which gives an error no the last line complaining that "No instance of constructor matches the argument list. Argument types are:
(std::vector<Wrapper<Statistics>, std::allocator<Wrapper<Statistics>>>)."
But isn't that exactly what I've defined the constructor to accept? at least the first part, I don't know what
std::allocator<Wrapper<Statistics>>
means.
Wrapper.h in case needed. It does the memory handling
#pragma once
#define WRAPPER_H
template< class T>
class Wrapper
{
public:
Wrapper()
{
DataPtr = 0;
}
Wrapper(const T& inner)
{
DataPtr = inner.clone();
}
~Wrapper()
{
if (DataPtr != 0)
delete DataPtr;
}
Wrapper(const Wrapper<T>& original)
{
if (original.DataPtr != 0)
DataPtr = original.DataPtr->clone();
else
DataPtr = 0;
}
Wrapper& operator=(const Wrapper<T>& original)
{
if (this != &original)
{
if (DataPtr != 0) {
delete DataPtr;
}
DataPtr = (original.DataPtr != 0) ? original.DataPtr->clone() : 0;
}
return *this;
}
T& operator*()
{
return *DataPtr;
}
const T& operator*() const
{
return *DataPtr;
}
const T* const operator->() const
{
return DataPtr;
}
T* operator->()
{
return DataPtr;
}
private:
T* DataPtr;
};

How can I copy all the objects from temporary object to another object

How can I copy all the objects to another set of objects. I created a temporary object so I can add the current "robot" to the "robotSquad". I am trying to dynamically add it
I am new to the concept of operator overloading, I might have the wrong assumption on what I'm doing. Im using the += operator, making a temp if there is no space in "robotSquad" adding it to temp then copying it to the original robotSquad named r_robot.
I could possibly be doing all this wrong, need help Thanks!
RobotSquad& RobotSquad::operator+=(const Robot& p_robot) {
if (count <= sizeof(r_robots)) {
//how do i copy?
RobotSquad temp[count+1];
temp[count]=p_robot;
for(int i=0 ;i<=sizeof(r_robots);i++){
temp[i]=r_robots[i];
}
} else {
this ->r_robots[count]=p_robot;
}
count++;
return *this;
}
class RobotSquad {
char* name ;
Robot *r_robots;
int count;
public:
//constructor
RobotSquad();
RobotSquad(Robot* , int, char* p_name= "No name");
~RobotSquad();
//getters
char* getName();
Robot* getRoster();
int getCount();
//setters
char setName();
Robot setRobot();
int setCount();
//other
RobotSquad& operator+=(const Robot&);
private:
void setEmpty();
};
With std, it could be:
class RobotSquad {
std::vector<Robot> robots;
std::string name;
public:
//constructor
RobotSquad() = default;
explicit RobotSquad(const std::vector<Robot>& robots,
const std::string& name= "No name")
: robots{robots}, name{name}
{}
~RobotSquad() = default;
RobotSquad& operator+=(const Robot& robot)
{
robots.push_back(robot);
return *this;
}
// ...
};

Observer const-correctness

I am trying to implement observer pattern into my project.
Imagine simple a class method
const Buffer * data() const
{
if (m_data)
return m_data;
// read some data from input
m_data = fstream.read(1000);
// subscribe to our buffer
m_data->Subscribe(this);
return m_data;
}
This method is used to read input data, but the operation could be time consuming, it is therefore delayed.
Class Buffer is simple wrapper above std::vector, which notifies observers, when it's data being altered.
The containing class needs to be notified, when Buffer data changes.
However, since this method is marked as const, I am unable to subscribe to the Buffer.
I was able to figure out 3 solutions:
1. Cast away const-ness
// subscribe to our buffer
m_data->Subscribe(const_cast<Object*>(this));
I am not sure, whether this is correct, but it works.
2. Change const-ness of notification method and observers
vector<const IModifyObserver*> m_observers;
void Subscribe(const IModifyObserver* observer);
void Unsubscribe(const IModifyObserver* observer)
virtual void ObserveeChanged(IModifyObservable*) const override
{
m_dirty = true;
}
This one has a downfall, if I need to change properties they all have to be mutable and all functions I call must be const, which also does not make any sense.
3. Remove const from everywhere
Buffer * data();
bool Equals(Object& other);
Buffer* m_data;
This would most probably mean, that I would have to remove const from whole solution, since I can't event call Equals for two different const objects.
How to properly solve this problem?
Full Code:
#include <vector>
using namespace std;
class IModifyObservable;
// class for receiving changed notifications
class IModifyObserver
{
public:
virtual void ObserveeChanged(IModifyObservable* observee) = 0;
virtual ~IModifyObserver() = 0;
};
// class for producing changed notifications
class IModifyObservable
{
public:
// Add new subscriber to notify
void Subscribe(IModifyObserver* observer)
{
m_observers.push_back(observer);
}
// Remove existing subscriber
void Unsubscribe(IModifyObserver* observer)
{
for (auto it = m_observers.begin(); it != m_observers.end(); ++it) {
if (observer == *it) {
m_observers.erase(it);
break;
}
}
}
// Notify all subscribers
virtual void OnChanged()
{
auto size = m_observers.size();
for (decltype(size) i = 0; i < size; ++i) {
m_observers[i]->ObserveeChanged(this);
}
}
virtual ~IModifyObservable() = 0;
private:
vector<IModifyObserver*> m_observers;
};
IModifyObserver::~IModifyObserver() {}
IModifyObservable::~IModifyObservable() {}
// Example class implementing IModifyObservable
class Buffer : public IModifyObservable
{
private:
vector<char> m_data;
};
// Example class implementing IModifyObserver
class Object : public IModifyObserver
{
public:
// Both share implementation
//Buffer * data();
const Buffer * data() const
{
// Just read some data
//m_data = fstream.read(1000);
// Subscribe to our buffer
m_data->Subscribe(this);
return m_data;
}
virtual void ObserveeChanged(IModifyObservable*) override
{
m_dirty = true;
}
// This is just for example, why do I need const data method
bool Equals(const Object& other) const { return data() == other.data();
}
private:
mutable Buffer* m_data = new Buffer();
bool m_dirty;
};
int main()
{
Object obj1;
Object obj2;
auto data1 = obj1.data();
auto data2 = obj2.data();
bool equals = (obj1.Equals(obj2));
}
What gets in the way here is you deferred reading. Without this optimisation the right way would be to separate constant and non-constant methods:
const Buffer * data() const
{
return m_data;
}
void InitializeData()
{
// Just read some data
m_data = fstream.read(1000);
// Subscribe to our buffer
m_data->Subscribe(this);
}
Then optimize it the way you want:
const Buffer * data() const
{
if(m_data == nullptr)
const_cast<Object*>(this)->InitializeData();
return m_data;
}
And you don't need m_data to mutable anymore.
BTW. To make this deferred initialization work you should initialize m_data member with nullptr. Otherwise this object will be created while constructing and your if(m_data) will be always true.
UPD
So here is another solution to your problem
class Object : public IModifyObserver
{
public:
Object()
: m_data(nullptr)
, m_dataInitialized(false)
// ...
{
m_data = new Buffer(); // << Create buffer here
m_data->Subscribe(this); // << And subscribe right away
}
const Buffer * data() const
{
if(!m_dataInitialized) // << Initialize if needed
{
// Set data here
m_data->setData(fstream.read(1000)); // << Probably you want to suppress notifications here
m_dataInitialized = true;
}
return m_data;
}
// ...
private:
mutable Buffer* m_data;
mutable bool m_dataInitialized; // << Added another flag to see if data was initialized
// ...
};
I took the liberty of refactoring your code, I couldn't see where the initial call to data() would happen in your example, but I imagine it is called in a 2-phase way (construct -> then call method). Sticking with the simple rule..
#include <algorithm>
#include <memory>
#include <vector>
using namespace std;
class IModifyObservable;
// class for receiving changed notifications
class IModifyObserver
{
public:
virtual void ObserveeChanged(IModifyObservable* observee) = 0;
virtual ~IModifyObserver() = default;
};
// class for producing changed notifications
class IModifyObservable
{
public:
// This method modifies state - so non-const
void Subscribe(IModifyObserver* observer)
{
observers_.push_back(observer);
}
// This method modifies state - so non-const
void Unsubscribe(IModifyObserver* observer)
{
observers_.erase(find(begin(observers_), end(observers_), observer));
}
// Again as the internal state of the observer is modified, this is non-const
virtual void OnChanged()
{
for (auto observer : observers_) {
observer->ObserveeChanged(this);
}
}
virtual ~IModifyObservable() = default;
private:
vector<IModifyObserver*> observers_;
};
// Example class implementing IModifyObservable
class Buffer : public IModifyObservable
{
vector<char> data_;
};
// Example class implementing IModifyObserver
class Object : public IModifyObserver
{
public:
// The first call to the non-cost version triggers the lazy load...
const Buffer* data()
{
if (!data_) {
data_ = make_unique<Buffer>();
// Now start the read operation
// :
// Subscribe, I imagine you only want to do this once?
data_->Subscribe(this);
}
return data_.get();
}
// Calls to const version returns what's there...
const Buffer* data() const
{
return data_.get();
}
// This has to be non-cost as the internal state is being modified
void ObserveeChanged(IModifyObservable*) override
{
dirty_ = true;
}
// Operator uses const versions, which will use const methods
friend
bool operator==(const Object& lhs, const Object& rhs) {
if (lhs.data() && rhs.data()) {
}
return false;
}
private:
unique_ptr<Buffer> data_;
bool dirty_ = false;
};
int main()
{
Object obj1;
Object obj2;
auto data1 = obj1.data();
auto data2 = obj2.data();
bool equals = obj1 == obj2;
}
There are no hacks, it should just work...
Avoid to register in the a getter, register in initialization:
class Object : public IModifyObserver
{
public:
Object() { m_data.Subscribe(this); }
const Buffer* data() const { return m_data; }
Buffer* data() { return m_data; }
void ObserveeChanged(IModifyObservable*) override { m_dirty = true; }
private:
Buffer m_data;
bool m_dirty = false;
};
With lazy initialization, it becomes:
class Object : public IModifyObserver
{
public:
Object() { m_data.Subscribe(this); }
Buffer& data()
{
if (!m_data.is_initialized()) { m_data.initialize(); }
return m_data;
}
const Buffer& data() const
{
if (!m_data.is_initialized()) { m_data.initialize(); }
return m_data;
}
void ObserveeChanged(IModifyObservable*) override { m_dirty = true; }
private:
mutable Buffer m_data;
bool m_dirty = false;
};
Demo

C++ - How to update pointer (or members) between instances of same class

I have a simple class which consists of a void pointer and an int (this is some sort of a boost::Variant educational project).
I also have a working copy constructor and a destructor.
But what grinds my gears is, how I would accomplish something like this:
Container cont1("some value"); //simple construction
Container cont2;
cont2.createLink(cont1); //this should initialize members with a reference (or something alike)
std::cout<<cont1; //yields "some value"
cont2.set(20); //setting this container should update the original container too, since I initialized with a reference (or smth alike)
std::cout<<cont1; //yields 20
This is the simplified version of the class:
class Container {
public:
Container(){}
Container(const std::string &val){var.type = STRING; var.data = new std::string(val);}
Container(int val){ /* same for int */}
Container(const Container &val){ /* do a memory copy */}
void set(int val){ /* set the value if type matches, otherwise allocate a new pointer */}
void set(const std::string &val){ /* the same as for int */}
void createLink(const Container &val){ /* somehow assign a reference or whatsoever */}
private:
typedef struct VAR {
int type = 0;
void *data = NULL; }
VAR var;
}
If I set the value of cont2 to a string (i.e. the same data type it holds at the moment), everything is fine, because the set would not allocate a new pointer and rather assign a new value.
But how do I make sure the pointer of cont1 updates if I assign a different value to cont2 and therefore have to allocate a new pointer?
Would I need something like shared_pointer?
Thanks for any insight!
EDIT:
I changed to function name to make it more clear what should happen.
There is a solution that only involves straight OO. You could create an interface for your variant type, and use double indirection to the variant instance to allow linked containers to share the same variant instance.
The reason double indirection is required is because of the way you want the set() method to automatically allocate a new variant instance if the new type doesn't match the original type. If we simply shared a pointer to the variant from both containers, then after set() creates a new variant instance, each container would be referring to different instances again.
To get around that, we can use a pointer to a pointer to a variant in the container instead.
Here is a possible way to define your variant interface, and how it could be subclassed:
typedef std::ostream Out;
struct BadType {};
struct Var {
virtual ~Var () = default;
virtual Out & print (Out &os) { return os << "(BadType)"; }
virtual void set (int) { throw BadType(); }
virtual void set (const std::string &) { throw BadType(); }
};
struct VarInteger : Var {
int data;
VarInteger (int v) : data(v) {}
Out & print (Out &os) { return os << data; }
void set (int v) throw() { data = v; }
};
struct VarString : Var {
std::string data;
VarString (const std::string &v) : data(v) {}
Out & print (Out &os) { return os << data; }
void set (const std::string &v) throw() { data = v; }
};
Here is how you could define your pointer to pointer, and how they could be initialized:
typedef std::shared_ptr<Var> VarPtr;
std::shared_ptr<VarPtr> varptr_;
static VarPtr make_var () { return std::make_shared<Var>(); }
static VarPtr make_var (int v) { return std::make_shared<VarInteger>(v); }
static VarPtr make_var (const std::string &v) {
return std::make_shared<VarString>(v);
}
VarPtr & var () { return *varptr_; }
const VarPtr & var () const { return *varptr_; }
Container () : varptr_(std::make_shared<VarPtr>(make_var())) {}
Container (int v) : varptr_(std::make_shared<VarPtr>(make_var(v))) {}
Container (const std::string &v)
: varptr_(std::make_shared<VarPtr>(make_var(v))) {}
And here is how your set() methods and createLink() method could be implemented.
void set (int v) {
try { var()->set(v); }
catch (BadType) { var() = make_var(v); }
}
void set (const std::string &v) {
try { var()->set(v); }
catch (BadType) { var() = make_var(v); }
}
void createLink (const Container &val) { varptr_ = val.varptr_; }
Demo
How about the following. Of course createLink cannot not take a const reference so I made it to take a non-const pointer.
class Container {
const int STRING = 0x0000001;
const int INT = 0x0000002;
const int LINK = 0x8000000;
public:
...
void set(int val){...}
void set(const std::string &val)
{
if (var.type == LINK)
{
reinterpret_cast<Container*>(var.data)->set(val);
}
else
...
}
void createLink(Container* val)
{
var.data = val;
var.type = LINK;
}
private:
typedef struct VAR {
int type = 0;
void *data = NULL;
};
VAR var;
};
There are a some important points to think about - relative lifetimes of the link and the linked is the most obvious one.

C++ Pass a argument through a class with array index?

class cat
{public:
void dog(int ID, char *value) // int ID I'd like to be the index array it was called from?
{
debug(ID, value);
}
}
cat cats[18];
cats[1].dog("value second arg, first arg auto filled from index array");
I want something similar to this.
include <vector>
class CatArray;
class Cat {
// This line means that the CatArray class can
// access the private members of this class.
friend class CatArray;
private:
static int ID;
public:
void dog(const char* value) {
// Use ID here any way you want.
}
};
int Cat::ID = 0;
class CatArray {
private:
std::vector<Cat> cats;
public:
explicit CatArray(unsigned int size) : cats(size) {}
Cat& operator [](unsigned int index) {
Cat::ID = index;
return cats[index];
}
};
But a little different. There are 18 Clients in a game and i need to basically do this. for eg, "Client 4 Chooses an option and the option gets called through the array index and than that way client 4 will call the function with the function holding the index 4"
Then cats[1] is not really a Cat object but a CatWithIndex object:
class Cat {
public:
void dog(size_t index,const char* value);
};
class CatWithIndex {
size_t index_;
const Cat &cat_;
public:
CatWithIndex(size_t index, const Cat &cat): index_(index), cat_(cat) {}
void dog(const char* value) {
cat_.dog(index_,value);
}
};
class CatArray {
private:
std::vector<Cat> cats;
public:
Cat& operator [](unsigned int index) {
Cat::ID = index;
return CatWithIndex(index,cats[index]);
}
};