Invoke a templated member from a c-function using void pointer - c++

My c++ code has to work with an underlying c-library. I have a c++ object that looks somewhat like this:
template <typename T>
class MyClass
{
public:
explicit MyClass(int x)
: mVar(x)
{
}
private:
int mVar;
};
Later in my c++ code I do the following:
auto p = new MyClass<int>(10);
call_c_lib_function((void*) p);
The c function saves the pointer 'p' in a larger c-structure. Later when the large
c object is getting destroyed, it invokes the delete handler.
void
c_delete_handler(void* data)
{
// data is holding the pointer value 'p' from above.
}
Since the object is getting destroyed, I need to free the object that allocated.
Per the c++ spec, 'delete void_ptr' is undefined since it doesn't know how to
invoke the appropriate destructor. How do I invoke delete on the appropriate
template object?
One solution I could think of was to create a wrapper structure around my MyClass pointer.
struct Wrapper {
enum template_type {
template_int,
template_double,
template_string,
...
};
int template_type;
void* obj_ptr;
};
before callign the call_c_lib_function, I'd do the following:
auto p = new MyClass<int>(10);
auto w = new Wrapper()
w.template_type = Wrapper::template_int;
w.obj_ptr = (void*) p;
call_c_lib_function((void) w);
and now in the delete handler, I can do the following:
void
c_delete_handler(void* data)
{
Wrapper* w = (Wrapper*) data;
switch (w->template_type) {
case Wrapper::template_int:
delete (MyClass<int>*) w->obj_ptr;
break;
case Wrapper::template_double:
delete (MyClass<double>*) w->obj_ptr;
break;
...
}
}
Is this a correct approach? is there a better alternative?
Would appreciate any inputs. Thanks.

Instead of using Wrapper, use a base class, if that's an option.
class MyBase
{
public:
virtual ~MyBase() {};
};
template <typename T>
class MyClass : public MyBase
{
public:
explicit MyClass(int x) : mVar(x) {}
private:
int mVar;
};
and then
void c_delete_handler(void* data)
{
Base* basePtr = reinterpret_cast<Base*>(data);
delete basePtr;
}
This approach obviates the need for keeping track of whether MyClass was instantiated using int, double, std::string, or ....

Related

Provide a pointer to member function to be invoked by the target class without functional

I'm reading a lot of questions (and answers) about function pointers, functors and callbacks but I still have a confusion about which is the right tool for me.
Some of them cannot apply to my scenario because it seems my compiler avr-gcc v5.4.0 does not have C++ standard library (i.e. std::function is not available).
This is my base class:
class Debouncer
{
public:
typedef uint8_t (Debouncer::*debouncer_raw_t) (void);
Debouncer() {}
void setRawFunction(Debouncer::debouncer_raw_t callback) { _raw = callback; }
private:
debouncer_raw_t _raw;
void anotherFunction()
{
uint8_t value = _raw();
// do something
}
}
In my other classes I have:
class Inputs
{
public:
Inputs()
{
_deb.setRawFunction(myRaw);
}
private:
Debouncer _deb;
uint8_t myRaw()
{
return something;
}
}
Of course this won't compile because myRaw is not static.
Anyway, I'm going to try to avoid this because it would break the existing code.
If I'm not wrong, a lot of questions seem to ask the other way around.
Instead I just want to pass the pointer of my member function to my Debouncer class, so it can call _raw() when it needs to.
Here I found this advise to avoid std:: library:
#define CALL_MEMBER_FN(object, ptrToMember) ((object).*(ptrToMember))
void userCode(Fred& fred, FredMemFn p) // Use a typedef for pointer-to-member types
{
int ans = CALL_MEMBER_FN(fred,p)('x', 3.14);
// Would normally be: int ans = (fred.*p)('x', 3.14);
// ...
}
But it seems the other way around. Here the class Fred is my Debouncer.
I don't want to call the Debouncer member, but member of the caller class (i.e. Input::myRaw()).
Would you please help me to understand which is the right tool to achieve such a simple task?
Making a member function virtual is a relatively low-overhead way to have a single pointer (to an object) refer to both the object's data and the correct member function.
class InputsBase
{
// All classes that implement myRaw() should inherit from this class
public:
virtual uint8_t myRaw() = 0;
};
class Inputs : public InputsBase
{
public:
Inputs()
{
_deb.setRawFunction(this);
}
private:
Debouncer _deb;
virtual uint8_t myRaw()
{
return something;
}
}
Your Debouncer can then simply store a pointer to the object in question.
class Debouncer
{
public:
typedef InputsBase* debouncer_raw_t;
Debouncer() {}
void setRawFunction(debouncer_raw_t callback) { _raw = callback; }
private:
debouncer_raw_t _raw;
void anotherFunction()
{
uint8_t value = _raw->myRaw();
// do something
}
}
If you know (or require) each of the classes using Debouncer have a public myRaw() function (or better operator(), or actually anything else), the problem is simpler:
template <typename T>
class Debouncer
{
public:
Debouncer (T* t): _t(t) {}
void anotherFunction()
{
uint8_t value = _t->myRaw();
std::cout << static_cast<int>(value);
}
private:
T* _t;
};
class Inputs
{
public:
Inputs() : _deb(this)
{
// beware, if Debouncer uses its parameter in constructor (like call a method),
// you cannot use initializer list
}
uint8_t myRaw()
{
return 13;
}
void foo()
{
_deb.anotherFunction();
}
private:
Debouncer<Inputs> _deb;
};
int main()
{
Inputs i;
i.foo();
}
This would be preferred solution in C++. See for example standard library <algorithm> - any function taking a predicate or some other callable expects to call it with operator() rathen than having to deal with pointers-to-member-function.
If you don't know what function should be called and you really cannot impose any requirement on the classes, you need to store both a pointer (or reference) to the class and a pointer to the member function. Note that you cannot connect pointers to member functions of different classes, so we need templates once again:
template <typename T, typename Func>
class Debouncer
{
public:
Debouncer (T* t, Func f): _t(t), _f(f) {}
void anotherFunction()
{
uint8_t value = (_t->*_f)(); //I get it now why isocpp asks to use macro here, the syntax is horrible
std::cout << static_cast<int>(value);
}
private:
T* _t;
Func _f;
};
class Inputs
{
public:
Inputs() : _deb(this, &Inputs::myRaw)
{
// beware, if Debouncer uses its parameter in constructor (like call a method),
// you cannot use initializer list
}
uint8_t myRaw()
{
return 13;
}
void foo()
{
_deb.anotherFunction();
}
private:
Debouncer<Inputs, decltype(&Inputs::myRaw)> _deb; //decltype is C++11, you could also declare type like you did in your question
};
int main()
{
Inputs i;
i.foo();
}

How would you design a function that attaches children of a Component class to an Object class if the components can hold different data?

In my program, I have an Object class to which we can attach components that all derive from a base Component class. Since a component can have data that are initialized through it's constructor, when we call Object::addComponent() we need to pass the data for this particular component
#include <vector>
class Component;
class Object
{
public:
Object() {}
/* The challenge comes from implementing this function, the signature will change later in this post
and ideally it would return the added component */
void addComponent();
private:
std::vector<Component*> m_components;
};
class Component
{
public:
Component(Object* owner) : m_owner(owner) {}
// Note the pure virtual destructor, meaning Component is meant to be derived
virtual ~Component() = 0;
private:
Object* m_owner;
};
Here are two Component derived classes for our example
// This component holds an int
class ComponentDerivedA : public Component
{
public:
ComponentDerivedA(Object* owner, int data) : Component(owner), m_data(data) {}
virtual ~ComponentDerivedA() override {}
private:
int m_data;
};
// This component holds a string
class ComponentDerivedB : public Component
{
public:
ComponentDerivedB(Object* owner, char* message) : Component(owner), m_message(message) {}
virtual ~ComponentDerivedB() override {}
private:
char* message;
};
The only solution I came for to implement the addComponent() function the way I want to is to create an enum and a struct:
enum class ComponentType { A, B };
struct ComponentInfo
{
ComponentType type;
int data;
char* message
};
So we change the signature for Object::addComponent() to the following
void* Object::addComponent(const ComponentInfo& info);
And here is a possible implementation
void* Object::addComponent(const ComponentInfo& info)
{
switch(info.type)
{
case A:
{
// We ignore cleaning up for this example but it would go in the destructor
ComponentDerivedA* a = new ComponentDerivedA(this, info.data);
m_components.push_back(a);
return a;
}
break;
case B:
{
// We ignore cleaning up for this example but it would go in the destructor
ComponentDerivedB* b = new ComponentDerivedB(this, info.message);
m_components.push_back(b);
return b;
}
break;
}
}
And here is how we would use it
int main()
{
Object obj;
ComponentInfo info{0};
info.type = ComponentType::A;
info.data = 5;
obj.addComponent(info);
/*
If I wanted to use the component right after I would have to do:
reinterpret_cast<ComponentDerivedA>(obj.addComponent(info)).doSomething();
*/
return 0;
}
This solution works okay but anytime you want to call addComponent() you have to declare a struct before, the only benefit is if you add multiple components you can reuse the same struct and just change the data between each call, also is if you add a new component type you have to expand the enum and the function, if you have many component the switch can become very large but the code inside it remains pretty repetitive and simple. And the final flaw is that it's up to the caller to cast the return value as the component type.
Here is a possible solution.
Note the use of std::unique_ptr instead of regular c-pointers.
#include <memory>
#include <vector>
struct Component{};
class Object {
public:
Object() {}
template <typename TDerivedComponent, typename... TArgs>
TDerivedComponent * addComponent(TArgs&&... args){
auto ptr = std::make_unique<TDerivedComponent>
(std::forward<TArgs>(args)...);
TDerivedComponent * result = ptr.get();
m_components.push_back(std::move(ptr));
return result;
}
private:
std::vector<std::unique_ptr<Component> > m_components;
};
struct ComponentA : public Component {
ComponentA(int x, int y){}
};
struct ComponentB : public Component {};
struct Invalid{};
int main(){
Object obj;
ComponentA * a = obj.addComponent<ComponentA>(1, 2);
ComponentB * b = obj.addComponent<ComponentB>();
// obj.addComponent<Invalid>(); -> error!
}
You actually can store a derived object into a baseclass object pointer which u already have declared as in the vector.
To make your derived objects also call the correct methods you have to declare the method as virtual inside the base class.
your addComponent() function can then take the pointer of the baseClass
addComponent(Component * c)
with that signature it can also take derived object pointers.
You should read about static vs dynamic binding in C++.

C++ compile time type determination

I have two classes deriving from the same base class. on compile time it is known which one gets created based on a macro define. I have another class that is a user and calls member functions (different ones for each class). It looks like this:
class User() {
void useClass( Base* p ) {
#ifdef useA
p->aFun();
#else
p->bFun()
#endif
}
class Base() {}
class A : public Base {
void aFun();
}
class B : public Base {
void bFun();
}
class C {
C() {
#ifdef useA
p = new A();
#else
p = new B();
#endif
}
Base* p;
User m_user;
void doStuffWithUser() {
user.useClass( p );
}
}
I would like to reduce the amount of macros, so I am wondering if there is a better way to do this. In particular, the #ifdef in the User class doesn't look very nice to me. Is there a way to reproduce it without using the macro? Ideally without runtime checks to determine what type p is.
EDIT:
The two derived classes have different members that need to be called and despite the inheritance, this cant be changed.
A solution is the visitor pattern.
The idea is to have two classes : the visitor and the visited.
The visitor is used to call a function depending on the real type of the object. The visited is the object of your class hierarchy.
In your example, you could do:
class User() {
void useClass( Base* p ) {
p->visit(visitor);
}
class Base() {
virtual void visit(Visitor) = 0;
}
class A : public Base {
void aFun();
virtual void visit(Visitor v) override {
v.visit(this);
}
}
class B : public Base {
void bFun();
virtual void visit(Visitor v) override {
v.visit(this);
}
}
class Visitor {
void visit(B* b) {
b->bFun();
}
void visit(A* a) {
a->aFun();
}
}
By having this double dispatch with the visit function, you ensure that you call the function depending on the real type.
I don't think there is a compile time solution to your issue because in useClass (as it is now), there is no way (at compile time) to know the real type of p. If you want to have a compile time solution you need to do more changes. For example making useClass a template or overloading it, which mean you can't call useClass with a Base* any more ...
The fact that A and B share a common base class is irrelevant since they have different interfaces that you are using.
I would make C a template and store a pointer to the derived class instead of the base class:
template<typename T>
class CT {
public:
CT() {
p = std::make_unique<T>();
}
std::unique_ptr<T> p;
User m_user;
void doStuffWithUser() {
user.useClass(p);
}
};
Then you can simply overload useClass() to accept either A or B:
class User {
public:
void useClass(A* p) {
p->aFun();
}
void useClass(B* p) {
p->bFun();
}
};
Now you just have one compile time switch:
#ifdef useA
using C = CT<A>;
#else
using C = CT<B>;
#endif
You can rename aFun and bFun to Fun and make it virtual(also add it in Base class) and in useClass, use Fun method, compiler will figure out which method to use.
This will eliminate first macro.
For the second maybe you should use rewrite it in some other way, so you wouldnt use macros at all. I don't think you can reproduce this behavior without macros.
Maybe you should have some flag that you give to constructor, 1 to create object A or 0 to create object B and get this flag from user at the runtime.
EDIT
So maybe you can create function Fun that in class A calls aFun and in class B calls bFun.
You can create a template for User class and specialize it for class A and class B:
template<typename T>
class User
{
void useClass( Base* p );
}
template<>
class User<A>
{
void useClass( Base* p ) {p->aFun();}
};
template<>
class User<B>
{
void useClass( Base* p ) {p->bFun();}
};
Now in class C:
template<typename T>
class C {
C() {
p = new T();
}
Base* p;
User<T> m_user;
void doStuffWithUser() {
m_user.useClass( p );
}
}
As a final note, just avoid using new operator. Try std::unique_ptr or std::shared_prt
PS. I have not tested this code
if you do not want to change any interface you can use single #ifdef
class Base {};
class A : public Base {
public:
void aFun(){}
};
class B : public Base {
public:
void bFun(){}
};
#ifdef useA
typedef A impl_type;
auto correct_func = &impl_type::aFun;
#else
typedef B impl_type;
auto correct_func = &impl_type::bFun;
#endif
class User {
public:
void useClass( Base* p ) {
auto pointer = (static_cast<impl_type*>(p));
(pointer->*correct_func)();
}
};
class C {
C() {
p = new impl_type();
}
Base* p;
User m_user;
void doStuffWithUser() {
m_user.useClass( p );
}
};
Probably you could name both functions with the same name in A and B and make it virtual, so useClass will call only needed function.
Like
class User() {
void useClass( Base* p ) {
p->fun();
}
};
class Base() {
virtual void fun() = 0;
};
class A : public Base {
void fun();
};
class B : public Base {
void fun();
};
Also you can use some kind of constexpr function (if you are using c++11 standard or newer) to determine what type p is.
Edit:
After seeing comment, i think that you're probably can left yours aFun(), bFun(), and just add some fun() func which will be derived and call type-specific function.
Also, it may be helpful to try and create some adapter classes with same interfaces(as in gof patterns).
Edit2: I mean that there could be some function like
constexpr Base* chooseType(int a){
if(a == 0){
return new A();
} else {
return new B();
}
}
/////
C() {
int case = 0;
p = chooseType(case);
}
And it will be called in compile-time, so as choice of class.
If you can't change the interface, want to get rid of #ifdefs, and have compile-time guarantee of types being used, without run-time checks - I would suggest using combination of templates, and overloaded functions.
First of all, I would change class C to be a template:
template<typename Type>
class C
{
static_assert(std::is_base_of<Base, Type>::value, "Template argument of C is not base of Base!");
public:
C () {p = new Type;}
~C() {delete p;}
void fun () {u.useClass (p);}
private:
Type* p;
User u;
};
And, then would change User class to switch between different possible implementations of Base with overloaded functions:
class User
{
public:
void useClass (A* p) {p->aFun();}
void useClass (B* p) {p->bFun();}
};
And, then you would create object of C as follows:
C<A> ca;
If you forgot to implement type-specific useClass, or tried to use wrong type in C (i.e. not inherited from Base), you would get compile-time errors.
In addition, if some of the child classes of Base, that you want to switch between, have non-default constructors, you may pass a functor (e.g. std::function<Type*()>) to a C constructor, and use that to create an object.
Such a constructor may look like:
C (std::function<Type* ()> function) {p = function();}
And usage of it would look like:
C<Z> cz ([&]{return new Z(someInt);});

convert pointer type in assignment

I have a class that has:
private:
uint32_t *data;
and the in one of the functions I'm doing:
void foo() {
data = new uint32_t[size];
}
and that is working fine. Now i wanted to make it a bit more flexible, so i wanted to make foo() a template:
template<typename T>
T foo() {
data = new T[size];
}
and i try to use it:
class.foo<uint64_t>();
But compilation fails saying that:
error: cannot convert 'long long unsigned int*' to 'unsigned int*' in assignment
Is it possible to do something like that? I tried declaring
void *data;
and it compiled, but then I cannot do
sizeof(data[1]);
which is essentially why I need to pass the type.
EDIT:
Thank you for your responses, there are a few thing I'd like to add after looking at your answers.
I'm using raw pointer instead of container because it operates on memory that is used also by external hardware (I'm not running this on PC).
Using this memory is optional for this class, so I don't want to allocate it if its not needed.
I use this class in a few places where I don't need *data at all, so I'd rather avoid making the whole class a template.
Another thought:
Default template type might be a good compromise, is there a way to create a class that I won't have to later use that way:
Class<> my;
but still:
Class my;
and if needed:
Class<type> my;
?
Rather than converting your function to a template, convert your class to a template:
template <class T>
class myclass {
private:
T *data;
public:
myclass(size_t size) : data(new T[size]) {
}
... // Add copy constructor, assignment operator, and a destructor
// to properly manage the pointer. See "rule of three" for more info.
};
This way the type of array element becomes part of the type of your class, letting your member functions work with the data without any additional type casting.
Note that using raw array pointer in the class comes with significant liabilities in terms of memory management. You would be better off with std::vector<T>.
You may consider making your whole class a template, like this:
template <typename T>
class Foo
{
private:
T *data;
public:
Foo(size_t size_):
data{new T[size]}
{
}
~Foo()
{
delete[] data;
}
};
Implementation is here only partial. See this about rule of 3, 5, 0.
Or using managed pointers:
template <typename T>
class Foo
{
private:
std::unique_ptr<T[]> data;
size_t size;
public:
Foo(size_t size_):
data{std::make_unique<T[]>(size_)},
size(size_)
{
}
~Foo()
{
// no need to call delete, unique_ptr will do it
}
};
But once you're here, depending on your use case, alternatives may be preferable, like std::vector:
std::vector<uint64_t> v(size);
// ...
std::cout << v.size() << std::endl;
EDIT:
From the additional information you provided, it looks like the following design may better suit your needs:
class Base
{
public:
virtual void* get_data() {
return nullptr;
}
virtual size_t get_size() {
return 0;
}
};
template<typename T>
class Foo : public Base
{
private:
T* data;
size_t size;
public:
Foo(size_t size_):
data{new T[size_]},
size(size_) {}
~Foo() {
delete[] this->data; // same remark as above about rule of 5
}
virtual void* get_data() overriden {
return this->data;
}
virtual size_t get_size() overriden {
return this->size;
}
};
With the following usage:
std::unique_ptr<Base> my_without_data =
std::make_unique<Base>();
std::unique_ptr<Base> my_with_data =
std::make_unique<Foo<type>>(size);
Note that in the second call, std::make_unique returns a unique_ptr<Foo<type>> with an appropriate deleter calling Foo<type>'s destructor. The deleter will be copied when assigning to my_with_data and call Foo<type>'s destructor even if Base's destructor is not declared virtual.
I chose here a design with virtual methods in Base to access data. Depending on your real use case, other ways may be used.
Convert your whole class to a templated class
template<typename T>
class Container {
public:
Container() :
data(NULL)
{}
~Container() {
if (data) {
delete [] data;
}
}
T* foo(int size) {
if (data) {
delete [] data;
}
data = new T[size];
return data;
}
private:
T *data;
};

Is it a good idea to use variadic templates to create a safer way to pass new objects

Lets say I have a class that has a data member that is a pointer to an abstract class Foo. One of the class's setters, setFoo asks for pointer to one of Foo's subclasses. What the programmer is supposed to pass is a new object of the subclass like setFoo(new FooBar(5, 10)); So that FooContainer is the only one holding a reference to the object and is the only one responsible for deleting that object. An example would be like...
class FooContainer final {
public:
FooContainer() : currentFoo(nullptr) {}
~FooContainer() {
delete currentFoo;
}
//Setter
void setFoo(Foo *foo) {
if (currentFoo != nullptr)
delete currentFoo;
currentFoo = foo;
}
//test that it holds the class
void fireFoo() {
currentFoo->func();
}
private:
Foo* currentFoo;
};
This has some big pitfalls like if I do these.
int main() {
FooContainer fc1;
holder.setFoo(nullptr); //Error passing a null pointer
holder.fireFoo();
//---
FooContainer fc2;
Foo* fooBar = new FooBar(5, 10);
holder.setFoo(fooBar); //Error now two objects hold references to fooBar
holder.fireFoo();
delete fooBar; //Error
return 0;
}
The solution I came up with was to use a variadic template function to set foo where it's passed the foo subclass type and varargs to construct whatever the new Foo subclass is, like this.
template <typename T, typename... Args>
void setFoo(Args... args) {
currentFoo = new T(std::forward<Args>(args)...);
};
So now I can do setFoo<FooBar>(5, 5); which insures that currentFoo is not a null pointer and the FooContainer is the only reference holder. Is this be the correct way to go about this? I've never encountered a problem like this before, and If I'm getting something wrong I can always fall back to unique pointers.
For ownership, you should use one smart pointer
Then you may use setter (which allows easily to have polymorphic Foo):
class FooContainer final {
public:
void setFoo(std::unique_ptr<Foo> foo) { // may be empty
currentFoo = std::move(foo);
}
void fireFoo() {
// may be empty if not set (constructor doesn't feed it) or set with nullptr
if (currentFoo) {
currentFoo->func();
}
}
private:
std::unique_ptr<Foo> currentFoo;
};
or internal factory (which ensures that you always have value)
class FooContainer final {
public:
template <typename...Ts>
explicit FooContainer(Ts&&... args) {
currentFoo = std::make_unique<Foo>(std::forward<Ts>(args));
}
template <typename...Ts>
void createFoo(Ts&&... args) {
currentFoo = std::make_unique<Foo>(std::forward<Ts>(args));
}
void fireFoo() {
assert(currentFoo); // Cannot be nullptr (except after moved currently ;) )
currentFoo->func();
}
private:
// You may even use `Foo currentFoo;` (which some changes above) if relevant
// (think about copy/move)
std::unique_ptr<Foo> currentFoo;
};