Save a pointer to member function of derived class - c++

I am looking for a way to save a pointer to a member function of a derived class.
For exemple:
class A
{
public:
typedef void (A::*FunctionP) (int a);
};
class B : A
{
public:
void Test(int a)
{
//Do stuff
}
B()
{
FunctionP theFunc = &B::Test;
}
};
The following code dose not compile..
Is there another way to do this? (Using template's maybe, or boost)
(Btw class A is an abstract class witch one of its implementations is invoking functions saved as FunctionP)
Thank you

Just use a static_cast:
FunctionP theFunc = static_cast<FunctionP>(&B::Test);
Coliru: http://coliru.stacked-crooked.com/a/2cfed4926aed43db
Still, it might be even better to use std::function and std::bind, depending on your needs.

Related

How to handle classes which "own" other classes

I want to make a base class which handles the construction of sub-classes. A sub-class then wants to call a function from the base class so I am passing it a pointer to be able to achieve this. The base class then passes back the sub-class to the user.
Is the below method an acceptable strategy for this? And is it safe to pass back an object in this fashion? If not, what would be a better alternative? I am concerned this becomes messy quickly as each subclass needs to be a friend for the base and it generally seems a bit clunky.
class SubClass
{
private:
SubClass(MyClass* parent) {
...
parent->DoStuff();
...
}
}
class MyClass
{
public:
SubClass CreateSubClass() {
return SubClass(this);
}
private:
void DoStuff() {
...
}
friend class SubClass;
}
MyClass a;
SubClass b = a.CreateSubClass();
Thanks in advance!
Nothing is really wrong with your code pattern. As super already mentioned in a comment, I'd probably pass a MyClass& reference instead of a MyClass* pointer.
If you want to reduce the class interdependencies and remove the need for friendship, you might pass a functor instead of the MyClass:
class SubClass
{
public:
template <class F>
explicit SubClass(F stuff_doer) {
...
stuff_doer();
...
}
};
class MyClass
{
public:
SubClass CreateSubClass() {
return SubClass([this] { DoStuff(); });
}
private:
void DoStuff();
};
Or if you don't want or can't have the SubClass constructor defined in a header file, instead of a constructor template you could use a std::function functor to erase the functor type:
class SubClass
{
public:
explicit SubClass(std::function<void()> stuff_doer);
};

How do you access member functions of a class object from within a different class object that has been created in it?

class Class1 //Would be object mClass1
{
public:
void Function1()
{
a++;
}
private:
int a = 0;
Class2 mClass2;
}
(Editing in a space here to clarify Class2 is not defined after Class1; they are in separate files.)
class Class2 //Would be object mClass2
{
public:
Function2()
{
Function1(); // Would be from mClass1
}
}
So Class1 creates an instance of a Class2 object, and that Class2 object has a member function that wants to access the "parent" object's member function, without using inheritance.
I don't know what I specifically need to search for to learn about this. Does it have to do with dereferencing a new pointer? Constructor type/initialization? Does it have a terminology? "Nested classes" bring up classes defined inside another class, which is not what this is.
Without inheritance there is no way to get the 'parent class'. So instead you should just pass the function as a parameter, maybe in the constructor of class 2 if you use it multiple times. See for example: https://www.cprogramming.com/tutorial/function-pointers.html
You cannot do this. Class2 is not known yet when you define Class1, so the Class1::mClass2 data member cannot possibly be created. But this problem can be solved by defining Class2 before Class1, and implementing Class2::Function2() outside the class and only after Class1.
As for calling Function1() inside Function2(), Class2 needs to know the object on which to call Function1(). You could use a reference member for that that you initialize in the constructor:
// Forward-declaration of Class1 so that Class2 will be able to define
// references or pointers to Class1.
class Class1;
class Class2
{
public:
// Constructor that requires a reference to our parent object.
explicit Class2(Class1& parent)
: parent_(parent)
{ }
// Just declare the function. We need to implement it later, outside
// this class definition because Class1 is not fully known yet and as
// a result we can't have calls to Function1() because the compiler
// doesn't know that function yet.
void Function2();
private:
// This is just a reference, so it works even if Class1 is not fully
// known yet.
Class1& parent_;
};
class Class1
{
public:
void Function1() { /* ... */ }
private:
int a = 0;
Class2 mClass2{*this}; // Pass ourself as the parent object.
};
// Class1 is fully known now, so we can do calls to Function1().
inline void Class2::Function2()
{
parent_.Function1();
}
This will work, but it has an important implication: it disables the assignment operator of Class2. This is probably what you want in this case, because two copies of Class2 should probably not have the same Class1 parent object.
However, I don't see why you need to do this. It complicates matters for no good reason. Why not simply pass the Class1 object that Function2() should use as a function argument instead? So:
class Class1;
class Class2
{
public:
void Function2(Class1& c1_obj);
};
class Class1
{
public:
void Function1() { /* ... */ }
private:
int a = 0;
Class2 mClass2;
};
inline void Class2::Function2(Class1& c1_obj)
{
c1_obj.Function1();
}
So whenever Class1 needs to call Class2::Function2(), just pass *this to it. It's simpler and doesn't have the drawbacks of holding a reference or pointer to another object.
With canonic classes - no way to do this, because Class2 is incomplete within Class1 and if you declare Class2 inside of Class1 (as a nested class), it wouldn't have access to Class1, because Class1 incomplete!
Looks like an unsolvable paradox? It is unsolvable in OOP land, but can be dodged just like Nikos had shown. But the problem of undefined types in some cases can be resolved in C++ or similar concept-oriented languages by using CRTP - Curiously recurring template.
If it is possible or not in your use-case and how complex it would be depending on what purpose you pursue. Here is an example of a paradoxical CRTP behavior - a member of base class is able to call a member of derived class:
#include <iostream>
template < class T>
class Base {
public:
template <class U>
struct Accessor : public U {
static void evoke_foo( T& obj)
{
return (obj.*(static_cast< void(T::*)() >(&Accessor::foo))) ();
}
};
void evoke( )
{
Accessor<T>::evoke_foo( *static_cast<T*>(this) );
}
};
class Derived : public Base<Derived> {
protected:
void foo() { std::cout << "Foo is called" << std::endl; }
};
int main()
{
Derived a;
a.evoke(); // evoke belongs to base.
}
Now if we'd want to determine return type of foo() automatically here, this would become an insanely complex piece of code. Some problems like that are solved in implementations of standard namesake of evoke method.

Calling derived class function from base class with templates without virtual

I need to generate some members/methods of a class with a script. I'm trying to break up this class in two, with base class being generated members, and derived class having hand coded members. However, I'm getting stuck in figuring out how to call derived member function D::f2() from the base class B::f1().
Here is the simplified code:
#include <cstdio>
template <typename _T>
class B {
public:
void f3() {
puts("okay");
}
void f1() {
f2(); // What C++ Magic to call f2() properly !!!
}
};
class D : public B<D> {
public:
void f2() {
f3();
}
};
int main() {
D d;
d.f1();
}
Is there any way, I can call D::f2() from B::f1() without using virtual functions ?
Added later:
If we do pointer manipulation, we will end up with injection, and I understand it's not a good idea, and I'll take the advice of not doing it. Let's stop that thread.
I am trying to find a solution using template only. I can generate any complex thing
for the generated code. It can even be a several functors etc. However the hand coded
written part should be hand-codable.
If you really really really want to do it:
static_cast<_T*>(this)->f2();
As people have mentioned, this is the curiously recuring template pattern!
This is a typical Curiously recuring template pattern. You can do:
template <typename _T>
class B {
public:
void f3() {
puts("okay");
}
void f1() {
static_cast<_T>(this)->f2();
}
};
You can use the Curiously Recurring Template Pattern.
A base class should have no notion of its children. Attempt to call a child method from base class is a sure sign of bad architecture. Virtual functions will not help you here by the way.
If you have to call a child's function from the base class you can do so just like you would do from any other function in your code. Still you will need an instance of the base class to call it on or alternatively you will have to static_cast the this pointer to a pointer of the child class type. This is a very bad idea!
There is another way, but at the cost of an ugly C style/reinterpret cast:
#include <cstdio>
#include <functional>
class B {
public:
typedef std::function<void (B*)> Function;
void f3() {
puts("okay");
}
void f1() {
_func(this);
}
Function _func;
};
class D : public B
{
public:
D()
{
_func = (void (B::*)()) &D::f2; // Here is the awfull cast I hate to do
}
void f2() {
f3();
}
};
int main() {
D d;
d.f1();
}
http://ideone.com/yOR0xT
I find this a lot less clean than the CRTP, because you have no compile time check...

C++: Design, Function template overriding and lack of polymorphism

Have a base class A, and a derived class B which overrides function template Func:
class A
{
A() {...};
~A() {};
template <class T>
void Func(const String &sInput, T &tResult)
{...}
};
class B : public A
{
B() {...}
~B() {};
template <class T>
void Func(const String &sInput, T &tResult)
{...}
};
(Note that Func is non-virtual, given the lack of support in C++ for templated virtual functions.)
Now have a mainprog API, class M:
class M
{
M(boost::shared_ptr<A> &pInterfaceInput): pInterface(pInterfaceInput)
{}
template <class T>
Evaluate(const String &sInput, T &tResult)
{
pInterface->Func<T>(sInput, tResult);
}
private:
const boost::shared_ptr<A> pInterface;
};
I want the function Evaluate here to support calls to functions on base class A or any of its derived classes (such as B). This class was written with polymorphism in mind before I re-designed class A and B to have templated functions.
Now the problem here is that if I pass a shared pointer of the base type to the derived type then Func of the base class will be called, not the derived class being pointed to.
How do I get around the lack of dynamic polymorphism here?
I've considered making class M a class template on the shared pointer type and having a static_cast in the constructor to ensure this type is of the base class type (A) or of a derived class.
What's the nicest way to do this? I'd prefer not to modify classes A and B to get around this problem but all suggestions are welcome.
Thanks.
Sounds like a double dispatch problem. Perhaps this would be a good place to implement the visitor pattern?
For example, create a class Evaluator, and for each T a subclass ConcreteEvaluator<T>. Give A and B methods that visit the Evaluator. Something like:
class Evaluator
{
virtual void visit_A(A* object);
virtual void visit_B(B* object);
};
template <typename T>
class ConcreteEvaluator : public Evaluator
{
public:
String* input_reference;
T& result_reference;
ConcreteEvaluator(String& input_reference_,T& result_reference_) :
input_reference(input_reference_),
result_reference(result_reference_) {}
virtual void visit_A(A* object) {
object->Func(input_reference,result_reference);
}
virtual void visit_B(B* object) {
object->Func(input_reference,result_reference);
}
}
class A
{
...
virtual void apply_evaluator(Evaluator *eval) {eval->visit_A(this);}
...
}
class B
{
...
virtual void apply_evaluator(Evaluator *eval) {eval->visit_B(this);}
...
}
For each subclass of A, a new method must be added to ConcreteEvaluator, so that this technique works best if A's class hierarchy is stable. And for each subclass of A, it must have an apply_evaluator function defined properly.
On the other hand, this may be total overkill. For about the same amount of work, you could always just pay the price to update M::Evaluate:
class M
{
...
void Evaluate(const String& sInput, T& tResult)
{
// try to downcast to each subclass of A. Be sure to check
// sub-subclasses first
try
{
dynamic_cast<B*>(pInterface.get())->Func(sInput, tResult);
return;
}
catch (std::bad_cast& ) { }
...
// nothing worked. It must really be an A
pInterface->Func(sInput,tResult);
}
...
};
I've show in the question Templatized Virtual function how to use type erasure to get some of the effects of virtual member function. Depending on what you want to do in Func(), you can use the same technique here.

How to pass method result as parameter to base class constructor in C++?

I've trying to achieve something like this:
class Base
{
public:
Base(string S)
{
...
};
}
class Derived: Base
{
public:
int foo;
string bar()
{
return stringof(foo); // actually, something more complex
};
Derived(int f) : foo(f), Base(bar())
{
};
}
Now, this doesn't work as I want, because bar() is called in the Derived constructor before foo is initialized.
I considered adding a static function similar to bar() which takes foo as a parameter - and using that in the initialization list, but thought I'd ask if there were any other techniques that could be used to dig myself out of this one...
Edit: Thanks for feedback - here's how I was going to handle the static function. Not sure if the overload between a static and non-static function is too clever, but...
class Derived: Base
{
public:
int foo;
static string bar(int f)
{
return stringof(f); // actually, something more complex
}
string bar()
{
return bar(foo);
};
Derived(int f) : Base(bar(f)) , foo(f)
{
};
}
Yes, using a function (static class method or regular function) that takes foo as a parameter and returns a string is a good solution. You can call this same function from Derived::bar to prevent code duplication. So, your constructor would look like this:
Derived(int f) : Base(stringof(f)), foo(f) {}
I place the call to the Base constructor first in the list to emphasize the order in which the initializations occur. The ordering of the initializer list has no effect as all class members are initialized in the order that they are declared in the class body.
This is a very clean, functional approach to the problem. However, if you still would like to weigh alternatives then consider using composition instead of inheritance for the relationship between the Derived and Base classes:
class Base {
public:
Base(string S) { ... }
void bat() { ... }
};
class Derived {
Base *base;
int foo;
public:
Derived(int f) : base(NULL), foo(f) {
base = new Base(bar());
}
~Derived() {
delete base;
}
string bar() {
return stringof(foo); // actually, something more complex
}
void bat() {
base->bat();
}
};
You will need to consider the pros and cons for your specific situation. With Derived holding a reference to Base you gain greater control over the initialization order.
You can only call static functions in the initializer list. The way you have it in your code:
class Derived: Base
{
public:
int foo;
string bar()
{
return stringof(foo); // actually, something more complex
};
Derived(int f) : foo(f), Base(bar())
{
};
}
Will still initialize Base first, and then foo. The order of how you write things in an constructor initializer list does not matter in any way. It will always construct in this order:
First, all virtual base classes
Then the non-virtual base classes in the order they appear in the base-classes list
Then all member objects in the order they are defined in the class definition.
Thus, you end up calling stringof with an uninitialized value. This problem is solved in boost::base_from_member. Also note that calling any nonstatic member function before all the constructor initializers of all base-classes completed is undefined behavior.
Calling static functions, however, is totally fine:
class Derived: Base
{
public:
int foo;
static string bar(int f)
{
return stringof(f); // actually, something more complex
};
Derived(int f) : Base(bar(f)), foo(f)
{
};
}
The base class constructor always gets called before initializing the other members of the derived class; your compiler should be giving you a warning for having the initializers in the wrong order. The only correct solution is to make bar() a static method that takes f as a parameter.
The constructor is for, well, constructing the object. This means that, until it returns, there isn't an object there, and therefore that calling member functions just isn't going to work reliably. As everybody else says, use a static function or a non-member function.
I've been wanting to do this as well, but I gave up in the end.
Any suitable function call could be used as the parameter of Base().
Another option is to add and alternative constructor to Base that takes an int and does the conversion to 'string' itself.
Just move your constructor code to an Initialize() function and call it from the constructor. This is much simpler than static/nonstatic overriding or anything like that.