Abstract base class + Functor

Discussion in 'C++' started by Gert Van den Eynde, Sep 23, 2003.

  1. Hi all,

    I'm struggling a bit with Functors generated for an ABC.

    This is the functor code:

    class Functor{
    public:
    virtual double operator(double x)=0
    }

    template <class T> class SpecFunctor: public Functor
    {
    private:
    double (T::*fpt)(double x);
    T* obj;
    }
    public:
    SpecFunctor(T* _obj, double(T::*_fpt)(double x))
    {
    obj = _obj; fpt = _fpt;
    }

    virtual operator()(double x)
    {
    (*obj.*fpt)(x);
    }

    Now, this works fine for 'ordinary' classes T. However, I would like to have
    it working for an ABC. When I use an ABC for T, I get warnings from g++
    that obj_ will get initialzed after... I more or less understand why the
    warnings appear (you cannot create an object for an ABC).

    It's merely warnings, but I would like to clean it up. Is there a way to do
    this without giving up the Functor or ABC?

    Thanks for any tips,

    gert
     
    Gert Van den Eynde, Sep 23, 2003
    #1
    1. Advertising

  2. Gert  Van den Eynde

    tom_usenet Guest

    On Tue, 23 Sep 2003 10:12:41 +0200, Gert Van den Eynde
    <> wrote:

    >Hi all,
    >
    >I'm struggling a bit with Functors generated for an ABC.
    >
    >This is the functor code:
    >
    >class Functor{
    >public:
    >virtual double operator(double x)=0
    >}
    >
    >template <class T> class SpecFunctor: public Functor
    >{
    >private:
    >double (T::*fpt)(double x);
    >T* obj;
    >}
    >public:
    >SpecFunctor(T* _obj, double(T::*_fpt)(double x))
    >{
    >obj = _obj; fpt = _fpt;
    >}
    >
    >virtual operator()(double x)
    >{
    >(*obj.*fpt)(x);
    >}
    >
    >Now, this works fine for 'ordinary' classes T. However, I would like to have
    >it working for an ABC. When I use an ABC for T, I get warnings from g++
    >that obj_ will get initialzed after... I more or less understand why the
    >warnings appear (you cannot create an object for an ABC).


    You don't show any code that tries to create an object of abstract
    type.

    >
    >It's merely warnings, but I would like to clean it up. Is there a way to do
    >this without giving up the Functor or ABC?


    Once I'd fixed the syntax errors, added virtual destructors, etc., it
    worked fine:

    class Functor{
    public:
    virtual ~Functor(){}
    virtual double operator()(double x) = 0;
    };

    template <class T>
    class SpecFunctor: public Functor
    {
    private:
    double (T::*fpt)(double x);
    T* obj;
    public:
    SpecFunctor(T* obj, double(T::*fpt)(double x))
    :eek:bj(obj), fpt(fpt)
    {
    }

    virtual double operator()(double x)
    {
    return (*obj.*fpt)(x);
    }
    };

    struct ABClass
    {
    ~ABClass(){}
    virtual double f(double d) = 0;
    };

    struct Derived: ABClass
    {
    virtual double f(double d)
    {
    return d * d;
    }
    };

    #include <iostream>

    int main()
    {
    Derived d;
    Functor* f = new SpecFunctor<ABClass>(&d, &ABClass::f);
    std::cout << (*f)(10) << '\n';
    }

    Or was that not what you meant?

    Tom
     
    tom_usenet, Sep 23, 2003
    #2
    1. Advertising

  3. >
    > Or was that not what you meant?
    >


    Yes, indeed. But compiling your code with g++ -Wall gives the same warnings:


    test.cc:26: warning: `struct ABClass' has virtual functions but non-virtual
    destructor
    test.cc:32: warning: `struct Derived' has virtual functions but non-virtual
    destructor
    test.cc: In constructor `SpecFunctor<T>::SpecFunctor(T*, double
    (T::*)(double))
    [with T = ABClass]':
    test.cc:44: instantiated from here
    test.cc:12: warning: `SpecFunctor<ABClass>::eek:bj' will be initialized after
    test.cc:11: warning: `double (ABClass::*SpecFunctor<ABClass>::fpt)(double

    The code works, as did mine, I just want to get rid of the warnings... I
    suppose that when the compiler generates them, there must be a cleaner
    way,no?

    gert
     
    Gert Van den Eynde, Sep 23, 2003
    #3
  4. Gert  Van den Eynde

    Attila Feher Guest

    Gert Van den Eynde wrote:
    >> Or was that not what you meant?
    >>

    >
    > Yes, indeed. But compiling your code with g++ -Wall gives the same
    > warnings:
    >
    >
    > test.cc:26: warning: `struct ABClass' has virtual functions but
    > non-virtual destructor


    struct ABClass
    {
    virtual ~ABClass(){}
    virtual double f(double d) = 0;
    };

    TADA :)

    --
    Attila aka WW
     
    Attila Feher, Sep 23, 2003
    #4
  5. > struct ABClass
    > {
    > virtual ~ABClass(){}
    > virtual double f(double d) = 0;
    > };
    >
    > TADA :)


    That one I figured out myself ;-) shouldn't have copy/pasted it... It's the
    'will be initialized after' that I wonder about...

    gert
     
    Gert Van den Eynde, Sep 23, 2003
    #5
  6. "Gert Van den Eynde" <> wrote in message
    news:bkp3hl$8va$...
    > [...]
    > That one I figured out myself ;-) shouldn't have copy/pasted it... It's
    > the 'will be initialized after' that I wonder about...


    template <class T>
    class SpecFunctor: public Functor
    {
    private:
    double (T::*fpt)(double x);
    T* obj;
    public:
    SpecFunctor(T* obj, double(T::*fpt)(double x))
    :eek:bj(obj), fpt(fpt)
    {
    }
    // ...
    };

    The order of initialization is determined by the order of the data
    members within the class, not the order of initializers in the c'tor.
    Therefore, if you give a different order in the c'tor, the compiler
    is warning you that it will not respect that ordering. To eliminate
    the warning, make the initializer list match the data member
    ordering.

    Dave
     
    David B. Held, Sep 23, 2003
    #6
  7. Gert  Van den Eynde

    tom_usenet Guest

    On Tue, 23 Sep 2003 11:25:07 +0200, Gert Van den Eynde
    <> wrote:

    >> struct ABClass
    >> {
    >> virtual ~ABClass(){}
    >> virtual double f(double d) = 0;
    >> };
    >>
    >> TADA :)

    >
    >That one I figured out myself ;-) shouldn't have copy/pasted it... It's the
    >'will be initialized after' that I wonder about...


    That's a good example of GCC's nanny warnings, where it annoys you by
    complaining about non-errors. Change the functor to:


    template <class T>
    class SpecFunctor: public Functor
    {
    private:
    double (T::*fpt)(double x);
    T* obj;
    public:
    SpecFunctor(T* obj, double(T::*fpt)(double x))
    :fpt(fpt), obj(obj) //re-ordered these
    //to match the declaration order.
    {
    }

    virtual double operator()(double x)
    {
    return (*obj.*fpt)(x);
    }
    };

    Tom
     
    tom_usenet, Sep 23, 2003
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Matthias Kaeppler
    Replies:
    1
    Views:
    471
    R.F. Pels
    May 22, 2005
  2. Sameer
    Replies:
    4
    Views:
    635
    Roedy Green
    Aug 31, 2005
  3. Uzytkownik
    Replies:
    3
    Views:
    610
    Uzytkownik
    Apr 3, 2005
  4. Iyer, Prasad C

    Abstract Methods & Abstract Class

    Iyer, Prasad C, Oct 20, 2005, in forum: Python
    Replies:
    0
    Views:
    552
    Iyer, Prasad C
    Oct 20, 2005
  5. Replies:
    4
    Views:
    866
    Rolf Magnus
    May 17, 2006
Loading...

Share This Page