C++ : function pointer and class members - c++

I have a problem with the following piece of code that can't even compile.
The problem is on the line
class2_ = new Class2(myFunction);
In fact, I don't now how to reference myFunction, I have also tried class2_ = new Class2(&Class3::myFunction); but the compiler still complains :(
2 constraints:
The function myFunction can't be declared as static
This code will be used in a Arduino base project, I can't use boost::bind
Could you please help me ?
Thanks.
class Class2 {
typedef void(*MyFunction) (int what);
MyFunction fn_;
public:
Class2(MyFunction fn) : fn_(fn) {}
void invoke(int val) {
fn_(val);
}
};
class Class3 {
Class2* class2_;
public:
Class3() {
class2_ = new Class2(myFunction);
class2_->invoke(12);
}
void myFunction(int what) {
// Do some work
}
};
void test2() {
Class3 instance3;
}

How about using an interface for that:
class ClassWithFunction {
public:
virtual void myFunction(int what) = 0;
}
class Class2 {
ClassWithFunction* fn_;
public:
Class2(MyFunction* fn) : fn_(fn) {}
void invoke(int val) {
fn_->myFunction(val);
}
};
class Class3 : ClassWithFunction {
Class2* class2_;
public:
Class3() {
class2_ = new Class2(this);
class2_->invoke(12);
}
void myFunction(int what) {
// Do some work
}
};

You need to use pointer to member function.
class Class3;
class Class2 {
typedef void(Class3::*MyFunction) (int);
MyFunction fn_;
public:
Class2(MyFunction fn) : fn_(fn) {}
void invoke(Class3 *p, int val) {
(p->*fn_)(val);
}
};
class Class3 {
Class2* class2_;
public:
Class3() {
class2_ = new Class2(&Class3::myFunction);
class2_->invoke(this, 12);
}
void myFunction(int what) {
// Do some work
}
};
If you want that Class2 accepts any callable object with signature void(int), then class template, function wrapper, lambda expression etc. will help.

Related

C++ workaroud virtual template method

i know there is nothing like virtual template method in C++, but as it seems it is exactly what i need. Is there any workaround i could use? I am thankful for any suggestion.
I would like to add Entities to a vector by a add method, which need to be virtual and also template, how to avoid this?
#include <iostream>
#include <vector>
class EntityBase {
public:
};
class EntityDerived1 : public EntityBase {
public:
};
class EntityDerived2 : public EntityBase {
public:
};
class ContainerBase {
public:
template<typename T>
virtual void add() = 0; // i know this is not allowed!!!
};
class ContainerConcrete : public ContainerBase {
public:
template<typename T>
void add() override { // i know this is not allowed!!!
data.push_back(std::make_shared<T>());
}
void doSecretStuffWithDataHere() {
// ...
}
private:
std::vector<std::shared_ptr<EntityBase>> data;
};
class Engine {
public:
Engine() :
container(std::make_shared<ContainerConcrete>())
{}
ContainerBase& getContainer() {
auto rawPointer = container.get();
return *container;
}
private:
std::shared_ptr<ContainerConcrete> container;
};
int main() {
Engine engine;
ContainerBase& container = engine.getContainer();
container.add<EntityDerived1>();
container.add<EntityDerived2>();
}
Just make add a regular virtual function that takes shared_ptr as a parameter
class ContainerBase {
public:
virtual void add(std::shared_ptr<EntityBase>) = 0;
};
class ContainerConcrete : public ContainerBase {
public:
void add(std::shared_ptr<EntityBase> p) override {
data.push_back(p);
}
// . . .
And then invoke it with make_shared for the desired type:
int main() {
Engine engine;
ContainerBase& container = engine.getContainer();
container.add(std::make_shared<EntityDerived1>());
container.add(std::make_shared<EntityDerived2>());
}
Alternatively you can add a templated overload that invokes make_shared:
virtual void add(std::shared_ptr<EntityBase>) = 0;
template<typename T>
void add() {
add(std::make_shared<T>());
}

Is it possible to have a virtual type in C++?

I have a class MyClass (with several virtual functions) that performs operations on an object called MyType.
The class MyClassImpl inherits MyClass and implements the virtual functions, but I need to add additional members to MyType, but I don't want to modify the class MyType (instead I want to keep it generic).
Now, if I make a MyTypeImpl and inherit MyType, I can add members. But, how do I make the non virtual functions in MyClassImpl (inherited from MyClass) use the new MyTypeImpl?
The only way I can think is to make MyClass use MyTypeImpl but I want to avoid using the implementation in the generic class because I might use various different implementations.
Here is a simple example of what the classes might look like. Of course, the code will not compile because the methods and members added in MyTypeImpl and not MyType.
class MyType {
public:
void increment() {
data_++;
}
protected:
int data_ = 0;
};
class MyClass {
public:
void alg() {
sub_routine_1();
sub_routine_2();
modify_mytype();
};
protected:
MyType mytype_;
virtual void sub_routine_1() = 0;
virtual void sub_routine_2() = 0;
void modify_mytype() {
mytype_.increment();
};
};
class MyTypeImpl : public MyType {
public:
void decrement() {
data_--;
is_decremented = true;
};
protected:
bool is_decremented = false;;
};
class MyClassImpl : public MyClass{
public:
void print() {
mytype_.print();
};
protected:
virtual void sub_routine_1() {
//do algorithm things here
mytype_.increment();
mytype_.increment();
};
virtual void sub_routine_2() {
//do more algorithm things here
mytype_.decrement();
mytype_.decrement();
};
};
After seeing your example I see now that you just want to extend the functionality of that class without modifying the original class. If you need to add additional functions, but you don't want to change the type that is stored in MyClass there isn't any way I know of to make that happen without at least modifying MyType to include virtual functions for the functions you want to call.
You also need to make MyClass take a pointer to MyType so you can use polymorphism and make the calls resolve to the correct implementation:
Dynamic Polymorphism Solution:
#include <iostream>
class MyType {
public:
virtual void increment() {
data_++;
}
// To be implemented by implementation class
virtual void print() = 0;
// To be implemented by implementation class
virtual void decrement() = 0;
protected:
int data_ = 0;
};
class MyTypeImpl : public MyType
{
public:
void print() {
std::cout << 42 << std::endl;
}
void decrement() {
data_--;
is_decremented = true;
};
protected:
bool is_decremented = false;;
};
class MyClass {
public:
MyClass(MyType* mytype)
: mytype_(mytype)
{}
void alg() {
sub_routine_1();
sub_routine_2();
modify_mytype();
};
protected:
MyType* mytype_;
virtual void sub_routine_1() = 0;
virtual void sub_routine_2() = 0;
void modify_mytype() {
mytype_->increment();
};
};
class MyClassImpl : public MyClass{
public:
MyClassImpl(MyType* mytype)
: MyClass(mytype)
{}
void print() {
mytype_->print();
};
protected:
virtual void sub_routine_1() {
//do algorithm things here
mytype_->increment();
mytype_->increment();
};
virtual void sub_routine_2() {
//do more algorithm things here
mytype_->decrement();
mytype_->decrement();
};
};
int main()
{
MyType* mytype = new MyTypeImpl();
MyClass* myclass = new MyClassImpl(mytype);
// Prints "42"
myclass->print();
// Do other stuff with "myclass"
delete myclass;
delete mytype;
}
Note, I am only using a raw pointer in this example for increased clarity. It is highly recommended that you don't use new and delete and use smart pointers to manage the lifetime of your pointers instead.
Static Polymorphism Solution:
Not that the design of this solution is actually any better, but I think this is closer to what you are actually looking for because it doesn't require modifying the MyType class directly. Also the only modification needed for MyClass is to make it a template class:
#include <iostream>
class MyType {
public:
virtual void increment() {
data_++;
}
protected:
int data_ = 0;
};
class MyTypeImpl : public MyType
{
public:
void print() {
std::cout << data_ << std::endl;
}
void decrement() {
data_--;
is_decremented = true;
};
protected:
bool is_decremented = false;
};
template <typename T>
class MyClass {
public:
void alg() {
sub_routine_1();
sub_routine_2();
modify_mytype();
};
protected:
T mytype_;
virtual void sub_routine_1() = 0;
virtual void sub_routine_2() = 0;
void modify_mytype() {
mytype_.increment();
};
};
template <typename T>
class MyClassImpl : public MyClass<T> {
public:
void print() {
this->mytype_.print();
};
protected:
virtual void sub_routine_1() {
//do algorithm things here
this->mytype_.increment();
this->mytype_.increment();
};
virtual void sub_routine_2() {
//do more algorithm things here
this->mytype_.decrement();
this->mytype_.decrement();
};
};
int main()
{
// Use the template to get the correct implementation
MyClassImpl<MyTypeImpl> myclass;
myclass.alg();
myclass.print();
// Do other stuff with my class
}

Is a C++ template able to "forward any class function" from parent class?

class Foo {
public:
void methodA();
};
class ManagedFoo {
Foo fooInst;
public:
void methodA() { doSomething(); fooInst.methodA();}
};
Now I want to make ManagedFoo as a template, managing any class not only Foo, and before any of Foo's function is called, call doSomething first.
template<typename _TyManaged>
class Manager {
_TyManaged _managedInst;
void doSomething();
public:
/*Forward every function called by _managedInst*/
/*How to write this?*/
};
I want to make it the same, make it replaceable between this two class, like this :
Foo* foo = new Foo();
foo->methodA();
Manager<Foo> managedFoo = new Manager<Foo>();
managedFoo->methodA(); //Hope it call Manager::doSomething() first then call _managedInst.methodA();
Can C++11 template do such thing? if answer is yes, how to?
Solution based on operator-> overloading:
#include <iostream>
#include <memory>
class A {
public:
void foo() { std::cout << "foo\n"; }
void bar() { std::cout << "bar\n"; }
};
template <typename T>
class ManagedBase {
std::shared_ptr<T> _inst;
public:
ManagedBase(const std::shared_ptr<T> inst) : _inst(inst) { }
virtual ~ManagedBase() { }
std::shared_ptr<T> operator->() {
before();
return this->_inst;
}
virtual void before() =0;
};
template <typename T>
class ManagedPrint : public ManagedBase<T> {
public:
ManagedPrint(const std::shared_ptr<T> inst) : ManagedBase(inst) { }
virtual void before() {
std::cout << "Said: ";
}
};
int main() {
auto ma = ManagedPrint<A>(std::make_shared<A>());
ma->bar(); // Said: foo
ma->bar(); // Said: bar
}
Something like this?
template<typename _TyManaged>
class Manager {
_TyManaged _managedInst;
void doSomething();
public:
_TyManaged* operator->() {
doSomething();
return &_managedInst;
}
};
This can solve your problem. But I'm still not sure what you want to do with your Manager class.
class Foo {
public:
void methodA();
};
template<typename T>
class ManagedFoo : public T {
public:
// some further extensions
};
And of course in this way you change the semantic of the Foo class by the manager from:
It has a
to
It is a
So I'm not sure if this is true in your case.

method as callback

I've implemented my callbacks with interface..
struct ICallback
{
virtual bool operator()() const = 0;
};
and function for adding a callback
void addCallback(const ICallback* callback) { .... }
and use, callback is in some class
class BusImplemantation{
public:
struct Foo : ICallback
{
virtual bool operator()() const { return true;}
}foo;
void OtherMethod();
int OtherMember;
};
But because callback is class(not function/method), I cant within callback access to OtherMethod and OtherMember. If callback would be not class, but only method than it would be possible.(inner class vs. method)
I cant pass OtherMethod and OtherMember to callback as parameters.
Is there any better solution for that? maybe with templates?
Use std::function:
void addCallback(const std::function<bool()>) { .... }
class BusImplemantation{
public:
bool Callback() { return true; }
void OtherMethod();
int OtherMember;
};
BusImplemantation obj;
addCallback(std::bind(&BusImplemantation::Callback, obj));
Check out boost::bind for a bunch of alternatives on how to implement this.
Could you do something like this instead:
typedef std::function<bool()> CallbackFunc;
void addCallback(const CallbackFunc callback) { .... }
class BusImplemantation{
public:
struct Foo
{
Foo(member) : OtherMember(member) { }
bool operator()() const { return true; }
void OtherMethod();
int OtherMember;
}foo;
};
Instead of making your callback an interface, make it use std::function to make it a function object (a Functor), and any extra data or methods that your functor needs can be a part of the functor class.
The whole point of using callback objects instead of free functions is that you can associate arbitrary state with them:
class BusImplemantation{
public:
struct Foo : ICallback
{
explicit Foo(BusImplementation &p) : parent(p) {}
virtual bool operator()() const;
private:
BusImplementation &parent;
} foo;
BusImplementation() : foo(*this)
{
addCallback(&foo)
}
void OtherMethod();
int OtherMember;
};
bool BusImplementation::Foo::operator() () const
{
if (parent.OtherMember == 0) {
parent.OtherMethod();
return false;
}
return true;
}
I think your ICallback interface must have pointer to controlled class with base interface, assume it BusImplemantation and inside callback use this pointer.
struct ICallback
{
virtual bool operator()() const = 0;
void setControlObject(BusImplemantation* o)
{
obj = o;
}
BusImplemantation* obj;
};
class BusImplemantation
{
public:
void addCallback(const ICallback* callback)
{
callback->setControlObject(this);
}
void OtherMethod();
int OtherMember;
};
And use:
class SomeCb : ICallback
{
bool operator()
{
obj->OtherMethod();
return true;
}
}

What's the simplest way to satisfy a pure abstract method with methods from other base classes

Edit: Per some comments, by simple I mean a) less code, b) easy to maintain, and c) hard to get wrong.
Edit #2: Also, using containment instead of private inheritance is not objectionable if it does indeed simplify the implementation of InterfaceImpl.
Currently, the only way I know to do this is to have the implementer define the abstract method and delegate the call to the target base type's method. Example:
#include <iostream>
#include <memory>
class Interface
{
public:
virtual void method1() = 0;
virtual void method2(int x) = 0;
};
class MethodOneImpl
{
private:
void method1(int x)
{ std::cout << "MethodOneImpl::method1() " << x << std::endl; }
public:
void method1() { method1(0); }
};
class MethodTwoImpl
{
public:
void myFunc(int x)
{ std::cout << "MethodTwoImpl::myFunc(x)" << x << std::endl; }
};
class InterfaceImpl : public Interface
, private MethodOneImpl
, private MethodTwoImpl
{
public:
virtual void method1() { MethodOneImpl::method1(); }
virtual void method2(int x) { MethodTwoImpl::myFunc(x); }
};
int main()
{
std::unique_ptr<Interface> inf;
inf.reset(new InterfaceImpl);
inf->method1();
inf->method2(0);
// This should be disallowed!
// std::unique_ptr<MethodOneImpl> moi;
// moi.reset(new InterfaceImpl);
}
At first, I thought that perhaps this might solve the problem:
class InterfaceImpl : public Interface
, private MethodOneImpl
, private MethodTwoImpl
{
public:
using MethodOneImpl::method1;
// Obviously this wouldn't work as the method names don't match.
//using MethodTwoImpl::???
};
The first using statement will make both MethodOneImpl::method1 methods be public, but it actually doesn't fulfill the contract with Interface, and it modifies the accessibility of MethodOneImpl::method1(int). And obviously we couldn't use this solution with method2 as the names don't match up.
FWIW, I have what I think is a solution, but it is not part of the standard at all (in other words it won't compile). I was thinking of making a proposal to the C++ committee; if anyone has any advice, I'd appreciate any comments below (but please dont' submit the advice as an answer).
An other option (at least if using MS VC++) is to use virtual inheritance:
struct MyInterface
{
virtual void Method1() = 0;
virtual void Method2() = 0;
};
class Method1Impl : public virtual MyInterface
{
virtual void Method1() { _tprintf( _T("Method1\n") ); }
};
class Method2Impl : public virtual MyInterface
{
virtual void Method2() { _tprintf( _T("Method2\n") ); }
};
class InterfaceImpl : public virtual MyInterface,
private Method1Impl,
private Method2Impl
{
};
void TestWeirdInterfaceImpl()
{
MyInterface* pItf = new InterfaceImpl();
pItf->Method1();
pItf->Method2();
}
While this seems to work and satisfy what you are looking for (asside from C4250 warning that you will have to suppress with a #pragma), this wouldn't be my approach. (I believe virtual inheritance is still not something that supported across all compilers, but I could be wrong).
I would probably go with containment and once boilerplate code is identifier, wrap it into some kind of macro map (similar to maps in ATL or MFC) that would make it really, really difficult to ever screw it up.
So this would be my macro approach:
struct MyInterface
{
virtual float Method1( int x ) = 0;
virtual int Method2( float a, float b ) = 0;
virtual void Method3( const TCHAR* sz ) = 0;
};
class Method1Impl
{
public:
float Method1( int x ) {
_tprintf( _T("Method1: %d\n"), x ); return 5.0;
}
};
class Method2and3Impl
{
public:
int Method2( float a, float b ) {
_tprintf( _T("Method2: %f, %f\n"), a, b ); return 666;
}
void Method3( const TCHAR* sz ) {
_tprintf( _T("Method3: %s"), sz );
}
};
#define DECLARE_METHOD0( MethodName, Obj, R ) \
virtual R MethodName() { return Obj.MethodName(); }
#define DECLARE_METHOD1( MethodName, Obj, R, A1 ) \
virtual R MethodName( A1 a1 ) { return Obj.MethodName( a1 ); }
#define DECLARE_METHOD2( MethodName, Obj, R, A1, A2 ) \
virtual R MethodName( A1 a1, A2 a2 ) { return Obj.MethodName( a1, a2 ); }
class InterfaceImpl : public MyInterface
{
public:
DECLARE_METHOD1( Method1, m_method1Impl, float, int );
DECLARE_METHOD2( Method2, m_method2and3Impl, int, float, float );
DECLARE_METHOD1( Method3, m_method2and3Impl, void, const TCHAR* );
private:
Method1Impl m_method1Impl;
Method2and3Impl m_method2and3Impl;
};
void TestWeirdInterfaceImpl()
{
MyInterface* pItf = new InterfaceImpl();
pItf->Method1( 86 );
pItf->Method2( 42.0, 24.0 );
pItf->Method3( _T("hi") );
}
Until C++ gods grace us with variadic macros, you'll have to declare one for each number of parameters you have. Also if you used multiple inheritance, potentially you wouldn't need the second "Obj" param, but as I've said before, I'd avoid multiple inheritance if there's another solution, which in this case is one extra param.
Yet a third option could be something that authors of Pragmatic Programmer seem to advocate a lot. If you have a ton of cookie cutter code that you don't want to repeat because, as you pointed out, it introduces human error. Define your own language and write a code generator script (python, perl...) to auto-create the actual code. In this case you could almost point at an interface, and have the script write the text out for you. I haven't tried doing this kind of thing myself, but lately have been wanting to use it somewhere just to see and evaluate the outcome.
This is sort of ugly and may bloat the executable size, but what about
#include <iostream>
class Interface
{
public:
virtual void method1() = 0;
virtual void method2(int x) = 0;
};
template<typename T>
class MethodOneImpl : public T
{
private:
void method1(int x)
{ std::cout << "MethodOneImpl::method1() " << x << std::endl; }
public:
void method1() { method1(0); }
};
template<typename T>
class MethodTwoImpl : public T
{
public:
void method2(int x)
{ std::cout << "MethodTwoImpl::myFunc(x)" << x << std::endl; }
};
class InterfaceImpl : public MethodTwoImpl<MethodOneImpl<Interface> >
{
};
int main()
{
InterfaceImpl impl;
impl.method1();
impl.method2(0);
}
class AbsInterface
{
// this is a simple interface class.
public:
virtual void Method1() = 0;
virtual void Method2() = 0;
};
class Functor1
{
public:
void operator () ()
{
printf("This Is Void Functor1");
}
};
class Functor2
{
public:
void operator () ()
{
printf("This Is void Functor2");
}
};
template <class T1, class T2>
class DerivedTemplateClass : public AbsInterface
{
public:
virtual void Method1() { T1()(); }
virtual void Method2() { T2()(); }
};
void main()
{
DerivedTemplateClass<Stratege1, Stratege2> instance;
instance.Method1();
instance.Method2();
}
as you can see, I used Functor.
You could work with template and functor.
It seems impossible to bring MethodOneImpl / MethodTwoImpl into the scope of Interface without having them inherit from Interface because they will not fill the Virtual Table if they don't. C++ misses something like the keyword implements from other languages.
So you are stuck with the virtual inheritence thing unless realize/accept that what you are looking for is just a bridge pattern, which does not satisfy requirement a) (you shall write more code), midly b) (code not necessarly difficult to maintain) and may satisfy c).
Here (another) possible solution (with only method though to reduce bloat)
class Interface
{ public:
virtual void method1() {return impl_->method1();}
private:
Interface() {}
protected:
struct Impl {
virtual void method1() = 0; };
std::shared_ptr<Impl> impl_;
Interface(const std::shared_ptr<Impl> &impl) : impl_(impl) {}
};
class InterfaceImpl : public Interface
{
struct Impl : public Interface::Impl {
void method1() { std::cout << "InterfaceImpl::method1() " << std::endl; } } ;
public:
InterfaceImpl() : Interface(std::shared_ptr<Impl> (new Impl)) {}
};
template <class T>
class GenericInterfaceImpl : public Interface {
struct Impl : public Interface::Impl {
Impl( T &t) : t_(t) {}
void method1() { t_.method1() ; }
T t_; };
public:
GenericInterfaceImpl() : Interface(std::shared_ptr<Impl> (new Impl(T()))) {}
};
struct AMethod1Impl {
void method1() { std::cout << "AMethod1Impl::method1() " << std::endl; } } ;
struct AnotherMethod1Impl_not_working {
void method1_not_present() { std::cout << "AnotherMethod1Impl_not_working ::method1_not_present() " << std::endl; } } ;
int main() {
// compilation of next line would fail
// (lame attempt to simulate ompilation fail when pure function not implemented)
// Interface inf;
std::unique_ptr<Interface> inf;
inf.reset(new InterfaceImpl);
inf->method1();
inf.reset(new GenericInterfaceImpl<AMethod1Impl>() );
inf->method1();
// compilation of next line would fail
// inf.reset(new GenericInterfaceImpl<AnotherMethod1Impl_not_working>() );
}
Does this serve your purpose?
It maintains the interface relationship and gives you maintainable code without having any consideration of client code.
Separating each method in functionoid and giving you the power to control the prototype of each method of the different base class.
#include <iostream>
#include <memory>
using namespace std;
//No Control over this.
class MethodOneImpl
{
private:
void method1(int x)
{ std::cout << "MethodOneImpl::method1() " << x << std::endl; }
public:
void method1() { method1(0); }
};
class MethodTwoImpl
{
public:
void myFunc(int x)
{ std::cout << "MethodTwoImpl::myFunc(x)" << x << std::endl; }
};
//*************************//
class Interface
{
public:
virtual void method1() = 0;
virtual void method2(int x) = 0;
};
//This is what i would do. //
class BaseFuncType
{
//no pure virtual
void Call()
{
throw "error";
}
void Call(int x)
{
throw "error";
}
};
class Method1: public BaseFuncType
{
auto_ptr<MethodOneImpl> MethodPtr;
public:
Method1()
{
MethodPtr.reset(new MethodOneImpl());
}
virtual int Call()
{
MethodPtr->method1();
}
};
class Method2: public BaseFuncType
{
auto_ptr<MethodTwoImpl> MethodPtr;
public:
Method2()
{
MethodPtr.reset(new MethodTwoImpl());
}
virtual int Call(int x)
{
MethodPtr->myFunc(x);
}
};
template <class T1>
class MethodFactory
{
private:
T1 methodObj;
public:
void CallMethod()
{
methodObj.Call();
}
void CallMethod(int x)
{
methodObj.Call(x);
}
};
class InterfaceImpl : public Interface
{
auto_ptr<MethodFactory> factory;
public:
virtual void method1()
{
factory.reset(new MethodFactory<Method1>());
factory->CallMethod();
}
virtual void method2(int x)
{
factory.reset(new MethodFactory<Method2>());
factory->CallMethod(x);
}
};
int main()
{
auto_ptr<Interface> inf;
inf.reset(new InterfaceImpl);
inf->method1();
inf->method2(10);
// This should be disallowed!
// std::unique_ptr<MethodOneImpl> moi;
// moi.reset(new InterfaceImpl);
}