Passing `this` to a function as a shared_ptr - c++

I am writing some example code that hopefully captures my current struggle.
Let's assume I have a class for some general shapes Shape
and a nice Function that doubles the perimeter of any shape
float DoublePerimeter (shared_ptr<Shape> shape)
return 2*shape->GetPerimeter();
};
Is it possible to use such a function in a class itself?
class Square : Shape {
float side = 1;
public:
void Square(float aside) : side(aside) {;}
float GetPerimeter(){return 4*side;}
void Computation() { DoublePerimeter (??????);}
};
What can I pass in the ?????? to make this work? I tried using something like
shared_ptr<Shape> share_this(this);
and also tried enable_shared_from_this<> for my class, however the pointer that I pass to the function always returns null on lock. Is this even possible, or is this bad design? Am I forced to make this function a member function?

If you don't want to use enable_shared_from_this, perhaps because your objects are not always owned by a shared pointer, you can always work around it by using a no-op deleter:
void nodelete(void*) {}
void Square::Computation() { DoublePerimeter({this, nodelete}); }
but it's a hack (and a fairly expensive one at that, since you're allocating and deallocating a control block just to con the function you're calling).
A cleaner solution, albeit one that might require more typing, is to separate your free function implementation from the ownership scheme:
float DoublePerimeter(Shape const& shape)
return 2*shape.GetPerimeter();
};
float DoublePerimeter(std::shared_ptr<Shape> shape)
return DoublePerimeter(*shape);
};
void Square::Computation() const { DoublePerimeter(*this); }

I've tried it out. It seems to work for me. See here or below. I fixed some small issues and made Computation return a value for demonstration purpose.
#include <memory>
#include <cassert>
#include <iostream>
class Shape {
public:
virtual float GetPerimeter(){return 0;}
};
float DoublePerimeter (std::shared_ptr<Shape> shape){
return 2*shape->GetPerimeter();
}
class Square : public Shape, public std::enable_shared_from_this<Square> {
float side = 1;
public:
Square(float aside) : side(aside) {}
float GetPerimeter(){return 4*side;}
float Computation() {
return DoublePerimeter (this->shared_from_this());
}
};
int main(){
auto square = std::make_shared<Square>(3.0);
std::cout <<square->Computation() << std::endl;
return 0;
}
edit:
Example for #pptaszni's comment. Changing the main to:
int main(){
Square square{3.0};
std::cout << (&square)->Computation() << std::endl;
return 0;
}
will result in a runtime error:
Program returned: 139
terminate called after throwing an instance of 'std::bad_weak_ptr'
what(): bad_weak_ptr

Related

c++ Overload operator variable (int) in class

I have simple class with multiple variable for the same type :
class Hello : public HelloPure
{
private :
int X;
int Y;
int Z;
I understand how overload work, but i can't find a way to make the following logic work :
mh->X/*Or GetX()*/ += somevalue;
mh->Y/*Or GetX()*/ += somevalue2;
mh->Z/*Or GetX()*/ += somevalue3;
I couldn't figure out how to reproduce a :
void operator +=(int &val, int val2);
That would not lead to a : "too many argument" error.
My main goal is to avoid the following :
mh->SetX(mh->GetX() + somevalue);
mh->SetY(mh->GetY() + somevalue2);
mh->SetZ(mh->GetZ() + somevalue3);
The reason is that my real environement is a lot more "heavy", and an overload may be more opptimise than the current solution.
Thanks you for future answer.
Edit/Update :
A good solution found user253751, but that doesn't work in my specific situation (i'll explain after) is to return a reference :
int &GetX();
and you canse us it :
a->GetX() += 5;
But in my situation i can't do that, i'm actually transfering information between c++ anb c#.
So i have a c++ Pure class pointer that i will use to compute my data, the pointer will be initialize with a CLI (c++/c#) class inheriting from my pure class, and the Cli pointer manage a pointer to my c# class.
When i do a GetX for exemple, it's more like that :
PurePointerClass->GetX()->will call the CLI class GetX() functiun
and in the GetX() { return m_PointerToManagedC#Object->GetX(); }
This make me unable to return directly a reference to my c# variable.
A common solution is to use one or more reference wrapper classes. Depending on how different your three cases really are, you may wish to use one wrapper with mutable data, or multiple wrappers:
class Hello {
void* m_PointerToManaged = nullptr;
public:
class XRef {
void* m_PointerToManaged;
public:
XRef(void* m_PointerToManaged) : m_PointerToManaged(m_PointerToManaged) { }
void operator+=(int) {
// your code
}
};
XRef GetX() { return {m_PointerToManaged}; }
class YRef {
void* m_PointerToManaged;
public:
YRef(void* m_PointerToManaged) : m_PointerToManaged(m_PointerToManaged) { }
void operator+=(int) {
// something else
}
};
YRef GetY() { return {m_PointerToManaged}; }
class ZRef {
void* m_PointerToManaged;
public:
ZRef(void* m_PointerToManaged) : m_PointerToManaged(m_PointerToManaged) { }
// maybe Zs cannot be added to?
//void operator+=(int) {
//}
};
ZRef GetZ() { return {m_PointerToManaged}; }
};
https://godbolt.org/z/8nW6c5
The resulting object still knows about the managed object (alternatively, you can also pass this and let it use common functionality of Hello), but it is now possible to specify addition operators for an object that is only responsible for one of the three different values.

c++ iterating over member functions

I have a bit of a design problem:
I have a class describing a Robot; It can move to different directions, move a camera to different views etc. It looks something like this:
class Robot {
private:
...
public:
void move_right();
void move_left();
void switch_camera()
void raise_camera()
}
I want to add another method which performs a series of events. Thing is, I need able to abort the events midway.
I do want to clarify that the robot is running on a micro controller and not on a standard OS - so I can't really send a signal to the process or anything.
My first idea was to store the event functions in an array and iterate over it:
#typedef void(robo_event *)(void)
robo_event next_event;
robo_event *event_sequence;
Robot() {
this->next_event = nullptr;
}
void perform_event_series() {
for(this->next_event = *event_sequence; this->next_event != nullptr; this->next_event+=sizeof(robo_event)) {
this->next_event();
}
}
void abort_event_series() {
this->next_event = nullptr;
}
Thing is, the c++ standard forbids storing addresses of member functions, so this is starting to get awkward. I can make the functions static, but I do need to use them quite frequently and that would still be awkward. I want to be able to change to event sequence without too much work if changes are yet to come, so I thought that saving those on some sort of array / vector would be the best.
Any help with c++ member function syntax / better ideas on how to approach this problem would be much appreciated.
Thing is, the c++ standard forbids storing addresses of member functions
C++ most certainly allows you to store pointers to member functions (and variables), but the syntax is a bit different to accommodate the this pointer type, virtual functions, inheritance, etc.
class Example
{
public:
double foo(int x) { return x * 1.5; }
};
int main() {
double (Example::* member_function_ptr)(int);
member_function_ptr = &Example::foo;
Example example;
std::cout << (example.*member_function_ptr)(2) << std::endl;
}
If all your functions are for the same class, same return type, same arguments, etc. then you can make a table of them easy enough.
Storing pointers to member functions is perfectly allowable in c++:
#include <vector>
class Robot {
private:
public:
void move_right();
void move_left();
void switch_camera();
void raise_camera();
};
struct Action
{
Action(void (Robot::*what)(void))
: what(what)
{}
void perform(Robot& who) const
{
(who.*what)();
}
void (Robot::*what)(void);
};
bool should_abort();
void perform_actions(Robot& who, std::vector<Action> const& actions)
{
for (auto&& action : actions)
{
if (should_abort()) break;
action.perform(who);
}
}
int main()
{
std::vector<Action> actions {
&Robot::move_right,
&Robot::raise_camera,
&Robot::switch_camera,
&Robot::move_left
};
Robot r;
perform_actions(r, actions);
}
Pointers to functions are of different types to pointers to members.
You need void(Robot::*)(void) not void(*)(void).
class Robot {
private:
typedef void(Robot::*robot_event)(void)
robo_event next_event;
robo_event *event_sequence;
Robot() {
next_event = nullptr;
}
void perform_event_series() {
for(next_event = *event_sequence; next_event != nullptr; ++next_event) {
(this->*next_event)();
}
}
void abort_event_series() {
next_event = nullptr;
}
public:
void move_right();
void move_left();
void switch_camera()
void raise_camera()
}

How can I avoid a virtual call when I know the type?

Consider the following code snippet:
struct Base { virtual void func() { } };
struct Derived1 : Base { void func() override { print("1"); } };
struct Derived2 : Base { void func() override { print("2"); } };
class Manager {
std::vector<std::unique_ptr<Base>> items;
public:
template<class T> void add() { items.emplace_back(new T); }
void funcAll() { for(auto& i : items) i->func(); }
};
int main() {
Manager m;
m.add<Derived1>();
m.add<Derived2>();
m.funcAll(); // prints "1" and "2"
};
I'm using virtual dispatch in order to call the correct override method from a std::vector of polymorphic objects.
However, I know what type the polymorphic objects are, since I specify that in Manager::add<T>.
My idea was to avoid a virtual call by taking the address of the member function T::func() and directly storing it somewhere. However that's impossible, since I would need to store it as void* and cast it back in Manager::funcAll(), but I do not have type information at that moment.
My question is: it seems that in this situation I have more information than usual for polymorphism (the user specifies the derived type T in Manager::add<T>) - is there any way I can use this type information to prevent a seemingly unneeded virtual call? (An user should be able to create its own classes that derive from Base in its code, however.)
However, I know what type the polymorphic objects are, since I specify that in Manager::add<T>.
No you don't. Within add you know the type of the object that's being added; but you can add objects of different types, as you do in your example. There's no way for funcAll to statically determine the types of the elements unless you parametrise Manager to only handle one type.
If you did know the type, then you could call the function non-virtually:
i->T::func();
But, to reiterate, you can't determine the type statically here.
If I understand well, you want your add method, which is getting the class of the object, to store the right function in your vector depending on that object class.
Your vector just contains functions, no more information about the objects.
You kind of want to "solve" the virtual call before it is invoked.
This is maybe interesting in the following case: the function is then called a lot of times, because you don't have the overhead of solving the virtual each time.
So you may want to use a similar process than what "virtual" does, using a "virtual table".
The implementation of virtual is done at low level, so pretty fast compared to whatever you will come up with, so again, the functions should be invoked a LOT of times before it gets interesting.
One trick that can sometimes help in this kind of situation is to sort the vector by type (you should be able to use the knowledge of the type available in the add() function to enforce this) if the order of elements doesn't otherwise matter. If you are mostly going to be iterating over the vector in order calling a virtual function this will help the CPU's branch predictor predict the target of the call. Alternatively you can maintain separate vectors for each type in your manager and iterate over them in turn which has a similar effect.
Your compiler's optimizer can also help you with this kind of code, particularly if it supports Profile Guided Optimization (POGO). Compilers can de-virtualize calls in certain situations, or with POGO can do things in the generated assembly to help the CPU's branch predictor, like test for the most common types and perform a direct call for those with a fallback to an indirect call for the less common types.
Here's the results of a test program that illustrates the performance benefits of sorting by type, Manager is your version, Manager2 maintains a hash table of vectors indexed by typeid:
Derived1::count = 50043000, Derived2::count = 49957000
class Manager::funcAll took 714ms
Derived1::count = 50043000, Derived2::count = 49957000
class Manager2::funcAll took 274ms
Derived1::count = 50043000, Derived2::count = 49957000
class Manager2::funcAll took 273ms
Derived1::count = 50043000, Derived2::count = 49957000
class Manager::funcAll took 714ms
Test code:
#include <iostream>
#include <vector>
#include <memory>
#include <random>
#include <unordered_map>
#include <typeindex>
#include <chrono>
using namespace std;
using namespace std::chrono;
static const int instanceCount = 100000;
static const int funcAllIterations = 1000;
static const int numTypes = 2;
struct Base { virtual void func() = 0; };
struct Derived1 : Base { static int count; void func() override { ++count; } };
int Derived1::count = 0;
struct Derived2 : Base { static int count; void func() override { ++count; } };
int Derived2::count = 0;
class Manager {
vector<unique_ptr<Base>> items;
public:
template<class T> void add() { items.emplace_back(new T); }
void funcAll() { for (auto& i : items) i->func(); }
};
class Manager2 {
unordered_map<type_index, vector<unique_ptr<Base>>> items;
public:
template<class T> void add() { items[type_index(typeid(T))].push_back(make_unique<T>()); }
void funcAll() {
for (const auto& type : items) {
for (auto& i : type.second) {
i->func();
}
}
}
};
template<typename Man>
void Test() {
mt19937 engine;
uniform_int_distribution<int> d(0, numTypes - 1);
Derived1::count = 0;
Derived2::count = 0;
Man man;
for (auto i = 0; i < instanceCount; ++i) {
switch (d(engine)) {
case 0: man.add<Derived1>(); break;
case 1: man.add<Derived2>(); break;
}
}
auto startTime = high_resolution_clock::now();
for (auto i = 0; i < funcAllIterations; ++i) {
man.funcAll();
}
auto endTime = high_resolution_clock::now();
cout << "Derived1::count = " << Derived1::count << ", Derived2::count = " << Derived2::count << "\n"
<< typeid(Man).name() << "::funcAll took " << duration_cast<milliseconds>(endTime - startTime).count() << "ms" << endl;
}
int main() {
Test<Manager>();
Test<Manager2>();
Test<Manager2>();
Test<Manager>();
}

Subclass unable to access parent class' variable

I'm making a program whereby I have a Square class which is a subclass of Shape class
But my program crashes when the subclass tries to access variable from parent class.
Here is my code:
class Shape2D
{
public:
string shape;
void setShape(string newShape);
string getShape();
string specialType;
void setSpecialType(string newSpecialType);
vector <int> shapeXCoordi;
void setshapeXCoordi(int newshapeXCoordi);
vector <int> shapeYCoordi;
void setshapeYCoordi(int newshapeYCoordi);
void toString();
virtual int computeArea()
{
return 0;
}
void displayArea();
};
For testing purpose, I only make this computeArea() return the x-coordinate.
class Square : public Shape2D
{
public:
int computeArea()
{
return shapeXCoordi[0];
}
};
int main()
{
if (aShape2D[0].getShape() == "Square")
{
Shape2D *pShape2D;
pShape2D = &aSquare;
cout << "Area: " << pShape2D -> computeArea() << endl;
}
}
I did a couple of test, if I were to change return shapeXCoordi[0]; to return 123;, it works fine.
I also tried return shape; but it will not display anything, although this time, it doesn't crash.
So I'm guessing there is something wrong when SquareClass is trying to access shapeXCoordi[0] from ShapeClass
Can anyone enlighten me on this situation?
You need to initialize the shapeXCoordi in your constructor by calling setshapeXCoordi first. Since you are accessing shapeXCoordi, an uninitialized vector, there are no elements in it. Hence when you access it using [0] it returns an error.
You can add a sanity check to computeArea() to ensure there is an element in shapeXCoordi before you access it:
int computeArea()
{
assert(shapeXCoordi.size() != 0);
return shapeXCoordi[0];
}
Also, I recommend using .at(0) instead of [0], this way you get actual error handling instead of a crash.

raw function pointer from a bound method

I need to bind a method into a function-callback, except this snippet is not legal as discussed in demote-boostfunction-to-a-plain-function-pointer.
What's the simplest way to get this behavior?
struct C {
void m(int x) {
(void) x;
_asm int 3;
}};
typedef void (*cb_t)(int);
int main() {
C c;
boost::function<void (int x)> cb = boost::bind(&C::m, &c, _1);
cb_t raw_cb = *cb.target<cb_t>(); //null dereference
raw_cb(1);
return 0;
}
You can make your own class to do the same thing as the boost bind function. All the class has to do is accept the function type and a pointer to the object that contains the function. For example, this is a void return and void param delegate:
template<typename owner>
class VoidDelegate : public IDelegate
{
public:
VoidDelegate(void (owner::*aFunc)(void), owner* aOwner)
{
mFunction = aFunc;
mOwner = aOwner;
}
~VoidDelegate(void)
{}
void Invoke(void)
{
if(mFunction != 0)
{
(mOwner->*mFunction)();
}
}
private:
void (owner::*mFunction)(void);
owner* mOwner;
};
Usage:
class C
{
void CallMe(void)
{
std::cout << "called";
}
};
int main(int aArgc, char** aArgv)
{
C c;
VoidDelegate<C> delegate(&C::CallMe, &c);
delegate.Invoke();
}
Now, since VoidDelegate<C> is a type, having a collection of these might not be practical, because what if the list was to contain functions of class B too? It couldn't.
This is where polymorphism comes into play. You can create an interface IDelegate, which has a function Invoke:
class IDelegate
{
virtual ~IDelegate(void) { }
virtual void Invoke(void) = 0;
}
If VoidDelegate<T> implements IDelegate you could have a collection of IDelegates and therefore have callbacks to methods in different class types.
Either you can shove that bound parameter into a global variable and create a static function that can pick up the value and call the function on it, or you're going to have to generate per-instance functions on the fly - this will involve some kind of on the fly code-gen to generate a stub function on the heap that has a static local variable set to the value you want, and then calls the function on it.
The first way is simple and easy to understand, but not at all thread-safe or reentrant. The second version is messy and difficult, but thread-safe and reentrant if done right.
Edit: I just found out that ATL uses the code generation technique to do exactly this - they generate thunks on the fly that set up the this pointer and other data and then jump to the call back function. Here's a CodeProject article that explains how that works and might give you an idea of how to do it yourself. Particularly look at the last sample (Program 77).
Note that since the article was written DEP has come into existance and you'll need to use VirtualAlloc with PAGE_EXECUTE_READWRITE to get a chunk of memory where you can allocate your thunks and execute them.
#include <iostream>
typedef void(*callback_t)(int);
template< typename Class, void (Class::*Method_Pointer)(void) >
void wrapper( int class_pointer )
{
Class * const self = (Class*)(void*)class_pointer;
(self->*Method_Pointer)();
}
class A
{
public:
int m_i;
void callback( )
{ std::cout << "callback: " << m_i << std::endl; }
};
int main()
{
A a = { 10 };
callback_t cb = &wrapper<A,&A::callback>;
cb( (int)(void*)&a);
}
i have it working right now by turning C into a singleton, factoring C::m into C::m_Impl, and declaring static C::m(int) which forwards to the singleton instance. talk about a hack.