Pointer to a child class method - class

So here's my code I'm working with:
#include <iostream>
class Node
{
public:
void speak(){std::cout << "I'm a base node" << std::endl;}
};
class Child : public Node
{
public:
void speak(){std::cout << "I'm a child node" << std::endl;}
};
int main()
{
Node node;
Child child;
node.speak();
child.speak();
std::cout << "= Pointers..." << std::endl;
Node* pnode = &node;
Node* pchild = &child;
pnode->speak();
pchild->speak();
}
And here's the output:
I'm a base node
I'm a child node
= Pointers...
I'm a base node
I'm a base node
The pchild->speak(); calls the Node's method and not the Child's one.
Now my problem is that I may have many different types of nodes, with varying number of connections. Thus I cannot declare a member pointer with a ChildX class, but only with a generic Node class. But each node will have a certain method that I want called.
I've tried to have a pointer to that method itself instead of to the class (since it would always be int (*foo)() type), but the compiler complains about invalid use of non-static member function.
So both of my approaches don't work. Neither pointer to a class, nor pointer to classes member function.

Familiarize yourself with virtual functions and polymorphism - both key concepts in c++.
In your question you simply need to define
virtual void speak(){std::cout << "I'm a base/child node" << std::endl;}

Related

Unable to bind rvalue reference arguments in member function

I'm using pybind11 to create python bindings for a C++ library whose source I cannot change. It contains a class that defines member functions with rvalue reference arguments (eg T &&val). I am unable to create a binding to a member function with rvalue reference arguments but binding to a non-member function with identical arguments works as expected.
A simplified example looks like this:
struct Foo {
// Cannot create a pybinding for this method.
void print_ref(int &&v) const {
std::cout << "Foo::print_ref(" << to_string(v) << ")" <<std::endl;
}
};
// Pybinding for standalone function works as expected.
void print_ref(int&& val) {
std::cout << "print_ref(" << to_string(val) << ")" << std::endl;
};
The pybind11 code looks like this:
PYBIND11_MODULE(refref, m) {
py::class_<Foo>(m, "Foo")
// Both of these attempts to create a pybinding FAILs with same error.
.def("print_ref", &Foo::print_ref)
.def("print_ref", (void (Foo::*) (int&&)) &Foo::print_ref);
// This pybinding of standalone function is SUCCESSful.
m.def("print_ref", &print_ref);
}
The compilation error on the first binding attempt is:
pybind11/bin/../include/site/python3.4/pybind11/pybind11.h:79:80: error: rvalue reference to type 'int' cannot bind to lvalue of type 'int'
initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(args...); },
^~~~
pybind11/bin/../include/site/python3.4/pybind11/pybind11.h:1085:22: note: in instantiation of function template specialization 'pybind11::cpp_function::cpp_function<void, Foo, int &&,
pybind11::name, pybind11::is_method, pybind11::sibling>' requested here
cpp_function cf(method_adaptor<type>(std::forward<Func>(f)), name(name_), is_method(*this),
^
refref.cpp:31:3: note: in instantiation of function template specialization 'pybind11::class_<Foo>::def<void (Foo::*)(int &&) const>' requested here
.def("print_ref", &Foo::print_ref);
Any ideas on what I may be doing wrong? Since it works fine with non-member functions, I'm inclined to suspect a pybind11 issue but thought I would check here first.
Indeed, the problem comes from rvalues. I learned quite a few things from this SO answer and this blog post.
There's a nice workaround : you can create a wrapper class that will redirect calls to the C++ library you cannot change, taking care of the rvalue with the std::move semantic.
#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
namespace py = pybind11;
struct Foo {
void print_ref(int&& v) const {
std::cout << "Foo::print_ref(" << +v << ")" <<std::endl;
}
};
// This class will interface between PyBind and your library
class Foo_wrap{
private:
Foo _mimu;
public:
void print_ref(int v) const{
_mimu.print_ref(std::move(v));
}
};
PYBIND11_MODULE(example, m) {
py::class_<Foo_wrap>(m, "Foo_wrap")
.def(py::init())
.def("print_ref", &Foo_wrap::print_ref);
}
That you can call in Python with
import example as fo
wr = fo.Foo_wrap()
wr.print_ref(2)

Passing a class member function to for_each

My question is: how do I pass a class member function into for_each
Code I am trying to get to work: (works when function is defined outside of class)
The part which fails is commented out - the one using for_each with function as the class member function
Any advice on how to get this to work?
#include <iostream>
#include <algorithm>
#include <vector>
void my_function(std::string str)
{
std::cout << "processing settings: " << str << std::endl;
}
class Settings_vector{
public:
std::vector <std::string> settings;
Settings_vector(){ // push back vector of objects
settings.push_back("settings 1");
settings.push_back("settings 2");
settings.push_back("settings 3");
settings.push_back("settings 4");
}
void tester(std::string settings_string){
std::cout << "processing settings: " << settings_string << std::endl;
}
};
int main()
{
//std::vector<std::string> my_vector;
Settings_vector settings_vector;
std:: cout << "doing things the non-class way\n" << std::endl;
for_each(settings_vector.settings.begin(), settings_vector.settings.end(), my_function); // testing function
// WORKS
/*
std:: cout << "doing things the modern way\n" << std::endl;
for_each(settings_vector.settings.begin(), settings_vector.settings.end(), settings_vector.tester); // testing function
// FAILS
*/
std:: cout << "doing things the oldskool way\n" << std::endl;
for (int i = 0;i<settings_vector.settings.size();++i) {
settings_vector.tester(settings_vector.settings[i]);
}
// WORKS
return 0;
}
The easiest way would be to use a lambda expression. A bit more complex approach is to use std::bind() to bind all known arguments (here the instance of the class to the member function) and leave unknown arguments with placeholders _1, _2, etc.
#include <iostream>
#include <algorithm>
#include <vector>
class Settings_vector
{
Settings_vector()
: settings { "settings 1"
, "settings 2"
, "settings 3"
, "settings 4"
}
{}
void tester(std::string settings_string)
{ std::cout << "processing settings: " << settings_string << std::endl; }
public:
std::vector <std::string> settings;
};
int main()
{
Settings_vector settings_vector;
using namespace std;
using namespace std::placeholders; // for _1
// Possibility Nr. 1: Use a Lambda Function
for_each( settings_vector.settings.begin(), settings_vector.settings.end()
, [&settings_vector](auto input){ settings_vector.tester(input); }
)
;
// Possibility Nr. 2: Partially bind existing arguments and use placeholders for others
for_each( settings_vector.settings.begin(), settings_vector.settings.end()
, std::bind(&Settings_vector::tester, &settings_vector, _1);
)
;
return 0;
}
Explanations:
I think a lambda is straight forward. In the square brackets, you declare what goes into a closure. Here we pass settings_vector. Preceding it with & means that this instance is passed by reference. In the parenthesis, we declare the parameters to the function. I cheated a little bit, as auto in lambda expressions was introduced in C++14, but you can write it as type std::string as well.
std::bind() binds parameters to a function pointer and returns a callable object. If all parameters are present, the returned callable has no parameters and can be called like: callable(). Here, we want a callable to accept the result of the iteration. Thus, we use a placeholder _1, which states that this argument will be changed at call-time. Now 2 things remain:
Getting a pointer to a member function. This is done by using &TypeName::MemberName, in this case &Settings_vector::tester.
Passing a this pointer to a member function call: &settings_vector. When calling a member function, an object must be passed for which this member function is called. Because we just got a pointer to a member function without any bound object to it, that's why the second param is &settings_vector.
For a more concise sintax, use a static class method. I've slightly edited your code for improved readability within the context of your question (aka removing distractions).
#include <iostream>
#include <vector>
class Settings {
public:
std::vector <std::string> settings;
Settings(std::initializer_list<std::string> l)
: settings(l) {
}
static void tester(std::string const& str) {
std::cout << "processing settings: " << str << std::endl;
}
};
int main() {
Settings sv {"settings 1", "settings 2", "settings 3", "settings 4"};
for_each(sv.settings.begin(), sv.settings.end(), Settings::tester);
return 0;
}

Shall I build a destructor in this classes?

I am currently working on building an ABM model using C++.
I have classes that have the need to interact with each other, because e.g. class B needs to examine values in class A and return some evaluation on it, which then class C might want to read. Classes need not to change other classes values, only to read from them.
Class B in my current implementation has a po
inter to a vector containing all members of Class A. The pointer is there for two order of reason: it makes easier to initialize the vector, and the vector is left in the scope of main so that I can access and loop over it, calling the members of class A for each agent.
My MCVE:
#include <iostream>
#include <vector>
using namespace std;
class A; // Forward declaration
class B{
int id,
some_value;
vector<A> * A_vec;
public:
// Overloaded constructor
B(int ID, vector<A> & PTR)
{
A_vec = & PTR;
id = ID;
some_value = 0;
};
// Copy Constructor
B( const B& that ):
id(that.id),
some_value(that.some_value)
{
// Pointer ??
};
// Non-default destructor -> uncomment leads to seg_fault
/*
~B(){ delete [] A_vec;};
*/
// Assignment operator
B& operator=(const B& that)
{
id = that.id;
some_value = that.some_value;
// Pointer ??
return *this;
};
//Methods to update different variables go here ..
void do_stuff();
};
class A{
B & class2_ref;
vector<double> o;
public:
int stuff;
// Overloaded constructor
A(int STUFF, B & REF, vector<double> O):
class2_ref(REF),
o(O)
{
stuff = STUFF;
};
// Methods to update different variables go here ..
};
void B::do_stuff()
{
int L = A_vec->size();
for(int l = 0; l<L; l++) some_value += (*A_vec)[l].stuff; // Perform some operation
};
int main(){
int I = 5; // Number of objects of A
vector<double> O(12,2); // Some numbers in here
B b(0,A_vec);
for(int i = 0; i< I; i++)
{
A a(i,b,O);
A_vec.push_back(a);
}
b.do_stuff();
cout<< "Debugging MCVE" << endl;
return 0;
}
My question then is:
Should I implement the destructor/copy constructor/assignment operator in class B? What about class A ? If so, can you please point me to the correct syntax(for the destructor the one above in comments leads to seg fault).
My understanding is that this might be one of the case in which I am happy with a "shallow" destruction of the pointer, because both class B and vector<A> will go out of scope at the return statement. class B owns the pointer, which gets destructed when it is due, and the same for vector.
But then, what about the other member from the rule of three?
There is only one object of class B planned, but I might (small chance) want to generalize later on.
if a class have a pointer type, you should implement a destructor, and i would suggest implementing a copy and an assignment operator as well, else you will be dealing with the same object from 2 different places, which could cause you some errors, for example -
void someFunction(B &b)
{
B a = b;
}
B b(0,A_vec);
someFunction(b); //After finishing someFunction, it will try to delete the vector from a , but it is the same vector you used in b.
b.do_stuff(); // Would cause a seg error
And for the destructor syntax, just delete the vector, not its content, it will use the vector default destrctor on the content:
delete A_vec
just make sure you dont use it if its not initialized, i would suggest just building a empty vector on each ctor of the class, that way you wont get a seg fault and you can use delete.

How to overload the << operator based on a method display already defined?

I would like to overload the << operator for my class from a method display already defined. I get an compiler error of no match for operator <<.
Here is a minimal example:
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass()
{}
ostream& display(ostream& out) const
{
out << "Display message" << endl;
return out;
}
ostream& operator<< (ostream& out) const
{
ostream& output = display(out);
return output;
}
};
int main()
{
MyClass C1;
cout << C1 << endl;
return 0;
}
Although C1.display(cout); woks without problems!
You have defined operator<< as a member function of MyClass. Therefore, you must call it like member functions are called (object on the left, parameter on the right), like this:
C1 << cout;
But that doesn't seem to be what you want. You probably want to be able to call it like this:
cout << C1;
In that case the function can't be a member of MyClass. It would have to be a member of cout, or a free function (outside any class). And in this case it must be a free function because you can't change the definition of cout.
So, to declare operator<< as a free function, it needs to have two arguments (left-hand-side and right-hand-side):
ostream& operator<< (ostream& out, const MyClass& c) { ... }
Now you can call it with an ostream on the left and a MyClass object on the right, like this:
cout << C1;

Inheritance with templates

#include<iostream>
using namespace std;
class C
{
public:
C (){};
virtual void nothing()=0;
virtual ~C (){};
};
class A : public C
{
public:
A (){};
virtual void nothing(){};
};
class B:public A
{
public:
B(){};
void nothing(){};
};
template <class T>
void hi(T){
cout << " i am something\n";
}
template <>
void hi<A>(A)
{
cout << " I am A\n";
}
template <>
void hi<B>(B)
{
cout << " I am B\n";
}
int main ( )
{
C *array [] = {new A,new B};
hi (*array [0]);
hi (*array [1]);
delete array [0];
delete array [1];
return 0;
}
Out:
i am something
I am something
Currently I am writing a program that has to deal with
Inherited types and specialised templates. In the example above I would l would like to see
I am A
I am B
Is there a way to properly invoke the functions corresponding to the objects although I am handling a base class array? I am not sure if type checking and conversion via dynamic_cast is the most elegant solution. Note that this is just an excerpt from a larger program.
Thank you in advance
In the main routine, the three lines shown below create an array of C*.
So any element of that array is treated as a C* regardless of
what the actual type of the element is.
That is, when you pass *array [0] to the function hi(),
the function that gets called is hi(C) which resolves to
the generic hi function, not either of the specialized functions.
C *array [] = {new A,new B};
hi (*array [0]);
hi (*array [1]);
In order to make hi<A> be invoked, you either have to store the pointer
to the new object in a variable of type A* or you need to cast the
C* to an A*.
In a case like this, a virtual function of C, overridden in A and B,
may serve the purpose better.