0

I have a parent class that looks something like this:

class Parent
{
    Parent(std::function<double(double)> func);
};

and a derived class that looks something like this:

class Derived : public Parent
{
    const double val;

    double MyFunc(double x)
    {
        return x / val;
    }

    Derived(double value)
        : Parent(std::function<double(double)>(&Derived::MyFunc)),
          val(value)
    {
    }
};

Basically, I want to restrict func from the parent class in a derived class. I know why what I've done above doesn't work; I've tried various other things like making MyFunc static; however, this doesn't help because then I can't use value, which again, makes sense...

Is there a good way to make this work?

Thank you.

Jean-Luc
  • 3,563
  • 8
  • 40
  • 78
  • _"I want to restrict func from the parent class in a derived class"_ I don't know what this sentence means. – Lightness Races in Orbit Sep 06 '14 at 17:53
  • I mean that as it stands, `func` can be anything. I want to derive a class that mostly, but not fully, defines `func` (I.e. I want to specify what `func` is in a derived class but also have that derived class pass it some parameters). – Jean-Luc Sep 07 '14 at 02:38
  • Still not clear. What problem are you trying to solve? – Lightness Races in Orbit Sep 07 '14 at 02:45
  • Okay, I'm not sure exactly how to explain, but basically `Parent` is a class that knows how to 'draw' a function (arbitrarily shaped waveguide) in a matrix (the matrix representing a grid of permittivities). I pass `Parent` the function I want to drawn, and then some other class receives the `Parent` object and draws it. Now, I want to derive off `Parent` and create a class that always draws sine wave shaped waveguides and accepts a parameter, `val`, that specifying the frequency of the sine wave. – Jean-Luc Sep 07 '14 at 02:54
  • Okay fine; just make it so the function is not invoked in the `Parent` constructor (which violates several design principles anyway) – Lightness Races in Orbit Sep 07 '14 at 02:55
  • So construct the object without that function, and then call a setter to set it after it has been constructed? That sounds a bit dodgy. Perhaps I can just make it pure virtual and create a class to override it everytime I want a new function... I wanted to avoid that. – Jean-Luc Sep 07 '14 at 03:02
  • You don't need a setter; you can _set_ the function just fine in the constructor but don't _call_ it there. And why did you want to avoid creating an interface? (which sounds perfect, FYI) – Lightness Races in Orbit Sep 07 '14 at 03:04
  • You can construct the object with "that function", but you cannot call/use "that function" from inside the constructor ... so call it from outside. – Slyps Sep 07 '14 at 03:06
  • Okay! Thanks. And I wanted to avoid the pure virtual approach because I didn't want to constantly have to derive a class every time I wanted to use a different function. I also wanted it to be possible to, say, just pass in a lambda function. I probably should've just done the pure virtual thing though... Something doesn't 'feel' so right about this approach. – Jean-Luc Sep 07 '14 at 03:52

2 Answers2

3

change this

    : Parent(std::function<double(double)>(&Derived::MyFunc)),

to

    : Parent(std::bind(&Derived::MyFunc, this, std::placeholders::_1)),
Slyps
  • 607
  • 4
  • 9
  • It seems to crash when I do this, I think because `this` hasn't been created when it is trying to initialise the derived class. It compiles though... – Jean-Luc Sep 06 '14 at 17:35
  • 1
    @Jean-Luc: [This use of `this` is safe](http://stackoverflow.com/a/5058365/560648). It is impossible to tell why your program is crashing, since you never presented a [testcase](http://sscce.org). – Lightness Races in Orbit Sep 06 '14 at 17:57
  • Okay, I must be doing something else wrong. Thank you. – Jean-Luc Sep 06 '14 at 17:58
  • Why have you accepted this answer when you haven't solved your problem yet? I have no idea what's going on with this question. – Lightness Races in Orbit Sep 06 '14 at 17:59
  • 2
    Could [this](http://coliru.stacked-crooked.com/a/57ebba9062af496c) be your problem? Only guessing as we have no idea what your program does. – Lightness Races in Orbit Sep 06 '14 at 18:01
  • @Lightness Races in Orbit I shouldn't have accepted it. My mistake. Yes the problem you've outlined in your example is my issue. Do you know of a way it could work? Thank you. – Jean-Luc Sep 07 '14 at 02:21
  • @Jean-Luc: No, I don't know enough (or, really, _anything_) about what you're trying to do. But it's clear that your base cannot do things with the derived class until the derived class is constructed. – Lightness Races in Orbit Sep 07 '14 at 02:32
  • His question basically was "Is there a way to make this work, so that I can also use `val`". He didn't specify **when** or **how** he wants to use `val` directly or indirectly. So the way I see it, both Jarod42s and my answer are correct for what he asked. The crash problem should maybe be elaborated in another question that provides a full SSCCE. – Slyps Sep 07 '14 at 03:20
  • @Slyps: Yes, and that lack of specification was the problem. – Lightness Races in Orbit Sep 07 '14 at 12:07
2

Alternatively to std::bind you may use lambda:

Parent([this](int x) { return this->MyFunc(x); })
Jarod42
  • 203,559
  • 14
  • 181
  • 302