Recombinate two complex attributes into new object - c++

I want to recombine a (complex) member attribute of two agents and put it in a new agent. It's a vector of numbers, every second value is taken from agent1, the rest from agent2. The problem is, I want to be able to exchange the implementation of my numberList, maybe another numberListInt2 using integers or like in my example using floats:
#include <vector>
using namespace std;
class NumberList {
};
class NumberListInt : public NumberList {
vector<int> number_list {1,2,3};
};
class NumberListFloat : public NumberList {
vector<float> number_list {1.2f,2.5f,30.0f};
};
class Agent {
NumberList* numbers;
public:
Agent();
Agent(NumberList* numbers) {
numbers = numberList*
}
~Agent() {
delete numbers;
}
NumberList* recombine(Agent& other) {
NumberList* new_number_list;
if(true) // a boolean config value
new_number_list = new NumberListInt();
else
new_number_list = new NumberListFloat();
for(unsigned int i=0;i<3;i++) {
if(i%2)
new_number_list[i] = other.get_number_list()[i];
else
new_number_list[i] = numbers[i];
}
return new_number_list;
}
NumberList* get_number_list() {
return numbers;
}
};
int main ()
{
Agent agent;
Agent agent2;
Agent agent3(agent.recombine(agent2));
return 0;
}
My questions:
How to implement the operator [] of NumberList?
Is there a better way than using a pointer for the polymorphism?
Do I free the memory correctly?
Thanks in advice!

The problem is that operator[] shall return a reference to an item of the NumberList. But you don't know the type of the numbers, when you're in the parent class. So you won't be able to define this operator in a polymorphic manner (unless you define somehow a polymorphic item).
To benefit from polymorphism you have to use references or pointers. In your case the pointers are a good alternative. However you have to clarify their use in the constructors. I assume that the copy constructor should copy the object and not reuse the list of the original agent.
No, because you have not defined a virtual destructor for NumberList. And when you recombine() you return a newly allocated list. So the caller has to delete the returned object. That's very dangerous: if he forget, memory will leak. You'd better consider opting for shared_ptr to avoid leaking.
It's not clear if you need dynamic change of the NumberList type at runtime. If you don't, a safer approach would be to use templates
With templates it would look like:
template <class T>
class NumberList {
vector<T> number_list;
T& operator[] (size_t i) { return numberlist[i]; } // may be add boundary check ?
};
template <class T>
class Agent {
NumberList<T> numbers; // No more pointer, but directly the object
....
};

Related

The element without default constructor in the custom template container

I need to create a simple template container, which can store any object of any type and could be used everywhere. So, I did something like this:
template <typename Type>
class Container {
public:
Container() : arraySize(10) { valueWrappers = new Type[arraySize];}
Container(const Container& other) { /* --- */}
~Container() { /* --- */}
Container& operator=(const Container& other) { /* --- */}
/* some functions */
private:
int arraySize;
Type* valueWrappers;
};
Now I have the problem - when I'm trying to create my container using as template a class without default constructor, the compilation error appears:
class MyClass {
public:
MyClass(int value) :v(value) { }
private:
int v;
};
int main() {
Container<MyClass> cont;
return 0;
}
C2512 'MyClass': no appropriate default constructor available
The problem is that I need to initialize the array of "Type" values with something, but I don't no what I need to use. I can't use NULL because, in this case, Container will work only with pointers. So, can somebody give an advice, how am I able to do it? Or, maybe, there is another way to solve this task?
Based on your requirements, I think you're going to have to use placement new. Since you haven't provided all the relevant code, I'm going to do what I can.
First, you're going to have to allocate raw memory instead of using new directly.
Container() : arraySize(10) { valueWrappers = reinterpret_cast<Type*>(::operator new(sizeof(Type) * arraySize)); }
Now when you put something in your Container, you'll have to construct it in place, using something like the following:
new (valueWrappers + index) Type(arguments to type);
In your destructor, you'll need to explicitly call the destructors on any object that you used placement new for.
valueWrappers[index]->~Type();
Lastly, release the memory using ::operator delete.
::operator delete(valueWrappers);
Please bear in mind that this is a very quick and dirty answer, and this code can be hard to debug and maintain. You're going to have to keep track of what indexes in valueWrapper have been initialized and which haven't during cleanup. If possible, I highly recommend using something akin to std::vector, which handles all this complexity for you.
One option is to not allocate the array in the default constructor, but initialise valueWrappers to null instead. Another option is to not have a default constructor in your template. Third option is to keep your class as-is and simply document that the template is default constructible only if the type argument is default constructible.
You can use std::optional to defer initialization, which is guaranteed to handle object lifetime correctly. Letting a default constructed container have 10 elements is also a questionable choice — a (count) constructor may be preferable.
template <typename Type>
class Container {
using elem_t = std::optional<Type>;
std::size_t count{};
std::unique_ptr<elem_t[]> elems{};
public:
Container() = default;
Container(std::size_t cnt)
: count{cnt}
, elems{std::make_unique<elem_t[]>(cnt)}
{
}
// for example
template <typename... Args>
void construct_at(std::size_t pos, Args&&... args)
{
assert(pos < count);
assert(!elems[pos]);
elems[pos].emplace(std::forward<Args>(args)...);
}
// ...
};
Note that I used std::unique_ptr to simplify memory management; a pointer will also be OK, though apparently more error-prone. Now you can traverse the container and construct the elements:
class MyClass {
public:
MyClass(int value) :v(value) { }
private:
int v;
};
int main()
{
Container<MyClass> cont(10);
for (std::size_t i = 0; i < 10; ++i) {
cont.construct_at(i, /* argument */);
}
}

Why can a Rcpp::Function be used as boost::function, and can it be introspected at runtime?

I have a vector<boost::function<void(void)>> -- essentially, a vector of function-like objects. The vector contains some Rcpp::Function objects, as well as some boost::function<void(void)> objects.
I have two questions about it. First off, I don’t really understand how this works, because as far as I can tell, Rcpp::Function isn’t a subclass of boost::function. How does the vector store these objects that don't have the same class? (Or do they share a class somehow?)
Second, and more important, I would like to be able to introspect the objects at runtime. I want to iterate over the vector and return a Rcpp::List representation of it: any Rcpp::Function objects will be added to the List, and any boost::function objects will simply be represented with an arbitrary string, like "C++ function".
In the example below, I have a C++ function test which takes an Rcpp::Function as input and adds to a vector. It also adds a boost::function<void(void)> to the vector. Then it iterates over the list, executing each function. The last part, which I haven't figured out, is how to build a List, where the item added to the list depends each item's type. Is this possible?
library(Rcpp)
cppFunction(
includes = '
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
void cpp_message(std::string s) {
std::cerr << s << "\\n";
}
',
code = '
Rcpp::List test(Rcpp::Function r_fn) {
std::vector<boost::function0<void> > fns;
// Add a Rcpp::Function to the vector
fns.push_back(r_fn);
// Add a boost::function<void(void)> to the vector
boost::function<void(void)> cpp_fn = boost::bind(&cpp_message, "bar");
fns.push_back(cpp_fn);
// Execute the functions to demonstrate the vector works
for (int i=0; i<fns.size(); i++) {
fns[i]();
}
// Create the List
Rcpp::List result;
for (int i=0; i<fns.size(); i++) {
// What I would like to do is something like:
// if (fns[i] is a Rcpp::Function) {
// result[i] = fns[i];
// } else {
// result[i] = "C++ function";
// }
}
return result;
}
',
depends = "BH"
)
test(function() message("foo"))
#> foo
#> bar
#> list()
(Note that the order of output lines can differ depending on how the environment buffers the output, so you may see it come out in a different order.)
How does the vector store these objects that don't have the same class?
Well, it is not the vector that stores such objects (directly), instead a newly created boost::function object inside the vector will store the instance. How would the this object do so?
Some simple demo class illustrates how this could be implemented:
// first need a generic template allowing the Demo<void(void)> syntax
template <typename S>
class Demo;
// now specialising (otherwise, we'd need to instantiate Demo<void, void>)
template <typename R, typename ... PP>
class Demo<R(PP...)>
{
class Wrapper
{
public:
virtual ~Wrapper() { }
virtual R operator()(PP...) = 0;
};
template <typename T>
class SpecificWrapper : public Wrapper
{
T t;
public:
SpecificWrapper(T& t) : t(t) { };
virtual R operator()(PP...pp) { return t(pp...); }
};
// the trick: pointer to POLYMORPHIC type!
Wrapper* w;
public:
// be aware that this constructor deliberately is NOT explicit
template <typename T>
Demo(T& t) : w(new SpecificWrapper<T>(t)) { }
R operator()(PP...pp) { return (*w)(pp...); }
};
The non-explicit constructor allows to implicitly create a new Demo object:
Rcpp::Function r; // simplified just for demo!
std::vector<Demo<void(void)>> v;
v.push_back(r); // implicit call to non-explicit constructor! equivalent to:
v.push_back(Demo<void(void)>(r));
Be aware that the class is just minimally implemented (solely the copy constructor; move constructor and appropriate assignment operators might yet be added), as it only serves for demonstration purposes.
I would like to be able to introspect the objects at runtime.
You're looking for std::function::target:
auto l = []() { std::cout << "demo" << std::endl; };
std::function<void(void)> f(l);
auto* pl = f.target<decltype(l)>();
if(pl)
(*pl)();
But that smells a bit of bad design, just like needing dynamic_cast (which Demo most likely would use on the wrapper pointer in its own variant of target). Why would you want to get this back? Wouldn't you rather just want to handle all functions alike, whether Rcpp or not?

Implement copy-on-write idiom in MyVector

I have my class which stores a collection of objects with their names
template <typename T>
class MyVector
{
private:
vector<T> objects;
vector<string> m_names;
size_t m_ref_ptr;
public:
MyVector()
{
m_ref_ptr = 1;
}
MyVector(const MyVector& other) : objects(other.objects),
m_ref_ptr(other.m_ref_ptr),
m_names(other.m_names)
{
m_ref_ptr++;
}
void push_back(const T& obj, const std::string& name)
{
copy_names();
objects.push_back(obj);
m_names.push_back(name);
}
void copy_names()
{
if (m_ref_ptr == 1)
{
return;
}
size_t temp_ref_ptr = 1;
vector<string> temp_names(m_names);
m_ref_ptr--;
m_ref_ptr = temp_ref_ptr;
m_names = temp_names;
}
The task is to use copy-on-write idiom for names for efficiency.
I tried something, but I am not sure why do we need this, if everything works okay in my class without this copy-on-write, I read about this idiom: the main idea is: we create real copy when we want to write something, with purpose to write.
My code is really simple. Please, give me a tipe how to do this in my code?
Sorry, can not add to the comments because I don't have enough reputation points yet, so I write this as answer:
Given m_names is a std::shared_ptr, in copy_names (and assuming using namespace std you write:
if (m_names.use_count() > 1) { // this is c++11
m_names = make_shared<vector<string>>(*m_names);
}
You can drop the m_ref_ptr member, because std::shared_ptr will keep track of this. In the constructor will have to create an empty vector:
MyVector()
{
m_names = make_shared<vector<string>>());
}
BTW, in your code the m_ref_ptr was not changing the reference count in the original object, i.e. if you would have done:
MyVector a;
...
MyVector b = a;
then you would still have a.m_ref_ptr == 1. std::shared_ptr takes properly care of this.

Holding Template Class Objects in Array

I have to hold different type of datas in one array for my project. I've created a template class for generating objects.
template<class Queue>
class Template {
public:
Queue value;
Template(Queue input) {
value = input;
}
};
But I can't hold them in one array without using abstract class. I've created a void pointer array for this. And I used it liked that;
void *array[21];
array[index] = new Template<int>(number);
array[index] = new Template<string>(text);
Is there any possible solution without abstract classes? I mean, can i hold this template objects in template class' array?
Create a hierarchy and take advantage of dynamic binding:
class Base {
public:
virtual ~Base() {};
// ...
};
template<class Queue>
class Template : public Base {
Queue value;
public:
Template(Queue const &input) :value(input) {}
// ...
};
And use it as:
Base *array[21];
array[index] = new Template<int>(number);
array[index + 1] = new Template<string>(text);
Furthermore, instead of using raw array and raw pointers use STL facilities like std::array smart pointers (e.g., std::shared_ptr<Base> or std::unique_ptr<Base>):
std::array<std::unique_ptr<Base>, 21> arr;
arr[index].reset(new Template<int>(number));
arr[index + 1].reset(new Template<string>(text));
Also prefer to initialize member variables to the constructor's initializer list than to its body.
This is usually a sign that you should rethink your code structure at a higher level so that you don't need this at all.
Otherwise you have four choices that I see (five if you count the "don't do this" above):
Use a uniform type that can hold all your types of data (for example a std::string and parse the numeric information out when needed). This functionality could be wrapped in a class that provides member functions to make this easier.
Use a boost::variant, if you are new to C++ then I don't recommend tackling this sort of thing right away.
Use a base class as explained by 101010. I would add that you may want an enum in the base class that tells you what type of data is stored
Use a boost::any, this is even more difficult to use than a variant, even though it's easier to understand.
Without more information on what it is you are trying to achieve, we can't really provide any better guidance on how to proceed.
I'd do it using variant types. You can roll out your own but prefer using boost::variant :
#include <boost/variant.hpp>
#include <iostream>
#include <string>
using namespace std;
template<class Queue>
class Template
{
public:
Queue value;
Template() = default;
Template(Queue input) {
value = input;
}
};
template<typename T>
std::ostream& operator<<(std::ostream& os, Template<T> const& t)
{
os << t.value;
return os;
}
int main ()
{
using v_t = boost::variant<Template<int>, Template<string>>;
v_t ar[2];
ar[0] = Template<int>(1);
ar[1] = Template<string>("lmfao");
for (auto&& elem : ar) cout << elem << endl;
}
Demo
Note that
v_t is the type of the variant
v_t can have more types among which you can choose to populate the array
the output operator was only overloaded for demonstration
you get extra functionality by boost::visitor

Recursive constructors in C++

I build a class for containing vectors with no default constructor. Specifically:
template<typename T>
struct MyVector
{
public:
int GetN(void)
{
return n;
}
MyVector(int n1)
{
n=n1;
ListElt = new T[n1];
}
~MyVector()
{
delete [] ListElt;
}
// some other irrelevant to the question code
private:
int n;
T *ListElt;
};
Now I want to build a class derived from it that contains one integer and a vector.
The code that works is the following:
struct EquivInfo {
public:
EquivInfo(int inpOrbit, MyVector<int> &inpMat)
{
iOrbit=inpOrbit;
eVect=new MyVector<int>(inpMat.getN());
// some code for copying the vector in place.
}
~EquivInfo()
{
delete eVect;
}
private:
int iOrbit;
MyVector<int> *eVect;
};
Is there a way to avoid the use of the pointer for the vector?
The problem is that if I remove the pointer then there is a call to a constructor of the kind MyVector(). I do not understand why. There should be a way to have a constructor for EquivInfo that calls a precise constructor for MyVector
I could add a constructor MyVector(), i.e. a default constructor that set the vector to something trivial. But precisely, I want to avoid such kind of constructors so that all vectors are well defined and the code is clean. The use of the pointer allows me to have a reasonable situation but I wonder if there is a clean way to avoid it.
Use member initializer list:
class EquivInfo {
public:
EquivInfo(int inpOrbit, MyVector<int> &inpMat)
: eVect(inpMat.getN())
, iOrbit(inpOrbit) {
// some code for copying the vector in place.
}
// ....
MyVector<int> eVect;
}