Defining a class on the fly

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Martin Magnusson

    Defining a class on the fly

    I want to create a few objects which all share a lot of common features,
    so they should all derive from the same base class. However, each of
    them needs individual definitions of two functions. So what I'd like to
    do is to create a new object which is based on a class with virtual
    functions, and define the virtual function when the object is created,
    without having to define a new class for each object. Is there a good
    way to do this in C++? (I know it's possible in Java.)

    I suppose another way to go is to use funtion pointers, but I's like to
    stay OO as much as I can.

    Thanks,
    Martin
  • Karl Heinz Buchegger

    #2
    Re: Defining a class on the fly



    Martin Magnusson wrote:[color=blue]
    >
    > I want to create a few objects which all share a lot of common features,
    > so they should all derive from the same base class. However, each of
    > them needs individual definitions of two functions. So what I'd like to
    > do is to create a new object which is based on a class with virtual
    > functions, and define the virtual function when the object is created,
    > without having to define a new class for each object. Is there a good
    > way to do this in C++? (I know it's possible in Java.)
    >
    > I suppose another way to go is to use funtion pointers, but I's like to
    > stay OO as much as I can.[/color]

    Could you reformulate?

    At the moment it sounds as if you want to create a class and more important
    the implementation of some functions during runtime.
    This is not possible in C++. At least not in a standard conforming way.
    The non standard solution would be: create a sort of plugin mechanism,
    write your C++ class definition to a file, start the C++ compiler from
    your application (if it can be found) and connect the new object module
    through the plugin mechanism. But none of the above is standard C++
    and to be honest: I never had the need for doing this.

    Just curious: What are this functions you want to create at runtime.
    If we know more about it, maybe someone might show you a C++ way to
    do it.

    --
    Karl Heinz Buchegger
    kbuchegg@gascad .at

    Comment

    • Jakob Bieling

      #3
      Re: Defining a class on the fly

      "Martin Magnusson" <mama7121@stude nt.uu.se> wrote in message
      news:3F338D9F.1 8B2E40E@student .uu.se...[color=blue]
      > I want to create a few objects which all share a lot of common features,
      > so they should all derive from the same base class. However, each of
      > them needs individual definitions of two functions. So what I'd like to
      > do is to create a new object which is based on a class with virtual
      > functions, and define the virtual function when the object is created,
      > without having to define a new class for each object. Is there a good
      > way to do this in C++? (I know it's possible in Java.)
      >
      > I suppose another way to go is to use funtion pointers, but I's like to
      > stay OO as much as I can.[/color]


      What do you mean exactly by 'defining' the function? How can you create
      code on the fly, unless you have a full C++ compiler embedded into your
      apps? If you have a set of function which you would like to assign
      dynamically, then use function pointers. Whether this is good design or not,
      I do not know .. what do you want to do this for?

      hth
      --
      jb

      (replace y with x if you want to reply by e-mail)


      Comment

      • Martin Magnusson

        #4
        Re: Defining a class on the fly

        Karl Heinz Buchegger wrote:[color=blue]
        > Could you reformulate?[/color]

        Sure! Say I have a class that looks something like this:

        class MaxNode
        {
        public:
        virtual float ValueOf( Sensation* s ) = 0;
        virtual bool IsTerminated( Sensation* s ) = 0;
        void AddChild( MaxNode* m );
        std::string ToString();
        private:
        Sensation* previousSensati on;
        Reward* previousReward;
        }

        Now, for each actual Max node I need to define what ValueOf() and
        IsTerminated() should do, and this will be different for all, or most,
        of the MaxNode objects I create.

        Naturally, I could write a new class for each object and then create a
        new object of that class, but since I would only create one object of
        each class, I would like to do something like this, which should create
        a pointer to an object called Root, which is of an unnamed class derived
        from MaxNode:

        MaxNode* Root = new MaxNode
        {
        float ValueOf( Sensation* s )
        {
        ...
        }
        bool IsTerminated( Sensation* s )
        {
        ...
        }
        // and possibly add some extra private fields:
        private:
        int extraData;
        };


        Does this make it any clearer?

        / Martin

        Comment

        • Jakob Bieling

          #5
          Re: Defining a class on the fly

          "Martin Magnusson" <mama7121@stude nt.uu.se> wrote in message
          news:3F33A48A.6 D743800@student .uu.se...[color=blue]
          > Karl Heinz Buchegger wrote:[color=green]
          > > Could you reformulate?[/color]
          >
          > Sure! Say I have a class that looks something like this:
          >
          > class MaxNode
          > {
          > public:
          > virtual float ValueOf( Sensation* s ) = 0;
          > virtual bool IsTerminated( Sensation* s ) = 0;
          > void AddChild( MaxNode* m );
          > std::string ToString();
          > private:
          > Sensation* previousSensati on;
          > Reward* previousReward;
          > }
          >
          > Now, for each actual Max node I need to define what ValueOf() and
          > IsTerminated() should do, and this will be different for all, or most,
          > of the MaxNode objects I create.
          >
          > Naturally, I could write a new class for each object and then create a
          > new object of that class, but since I would only create one object of
          > each class, I would like to do something like this, which should create
          > a pointer to an object called Root, which is of an unnamed class derived
          > from MaxNode:
          >
          > MaxNode* Root = new MaxNode
          > {
          > float ValueOf( Sensation* s )
          > {
          > ...
          > }
          > bool IsTerminated( Sensation* s )
          > {
          > ...
          > }
          > // and possibly add some extra private fields:
          > private:
          > int extraData;
          > };
          >
          >
          > Does this make it any clearer?[/color]


          Yes :o)

          I assume only those functions will change and the rest will remain
          untouched? In this case, you have a some options.

          a) You create have a function pointer to a 'regular' function in the
          class and assign it a pointer to the wanted function on runtime. It is only
          ugly when calling, since it will look a bit like C with emulated classes:
          my_class.do_fun c (myclass, params);

          b) The same as a), but with member functions. Though, the calling syntax
          looks really ugly: (my_class.*my_c lass.do_func) (params);

          c) Probably the cleanest approach: You make your class a template, that
          takes an id (either an int or a value of an enum). Then you create the
          /non/-virtual functions ValueOf etc. Inside those functions you put a huge
          switch statement that executes code based on the template parameter of the
          class. If you have a good optmizing compiler it will just insert the code
          thats needed and remove the switch altogether (since the template parameter
          is a compile time constant and you would be switching on that). The
          advantage I see, you have all the code of the different 'MaxNode types' in
          one place. the disadvantage, your functions in question might become
          awefully large.

          hth
          --
          jb

          (replace y with x if you want to reply by e-mail)


          Comment

          • Karl Heinz Buchegger

            #6
            Re: Defining a class on the fly



            Martin Magnusson wrote:[color=blue]
            >
            > Karl Heinz Buchegger wrote:[color=green]
            > > Could you reformulate?[/color]
            >[/color]

            Just to clearify
            [color=blue]
            > Sure! Say I have a class that looks something like this:
            >
            > class MaxNode
            > {
            > public:
            > virtual float ValueOf( Sensation* s ) = 0;
            > virtual bool IsTerminated( Sensation* s ) = 0;
            > void AddChild( MaxNode* m );
            > std::string ToString();
            > private:
            > Sensation* previousSensati on;
            > Reward* previousReward;
            > }
            >
            > Now, for each actual Max node I need to define what ValueOf() and
            > IsTerminated() should do, and this will be different for all, or most,
            > of the MaxNode objects I create.[/color]

            But you know at compile time, what those functions should do? Your original
            post sounded as if even that decision should be delayed until runtime.
            [color=blue]
            >
            > Naturally, I could write a new class for each object and then create a
            > new object of that class, but since I would only create one object of
            > each class, I would like to do something like this, which should create
            > a pointer to an object called Root, which is of an unnamed class derived
            > from MaxNode:
            >
            > MaxNode* Root = new MaxNode
            > {
            > float ValueOf( Sensation* s )
            > {
            > ...
            > }
            > bool IsTerminated( Sensation* s )
            > {
            > ...
            > }
            > // and possibly add some extra private fields:
            > private:
            > int extraData;
            > };
            >
            > Does this make it any clearer?[/color]

            So your goal is to not have to write all those classes by hand.
            Well. Let the compiler do it. Seems like what you want is a templated
            class, which takes 2 functions as the template arguments.

            Unfortunately I am not good in templates, so I drop out right now.
            Anyone else?

            --
            Karl Heinz Buchegger
            kbuchegg@gascad .at

            Comment

            • Kevin Goodsell

              #7
              Re: Defining a class on the fly

              Martin Magnusson wrote:
              [color=blue]
              > I want to create a few objects which all share a lot of common features,
              > so they should all derive from the same base class. However, each of
              > them needs individual definitions of two functions. So what I'd like to
              > do is to create a new object which is based on a class with virtual
              > functions, and define the virtual function when the object is created,
              > without having to define a new class for each object. Is there a good
              > way to do this in C++? (I know it's possible in Java.)
              >
              > I suppose another way to go is to use funtion pointers, but I's like to
              > stay OO as much as I can.
              >
              > Thanks,
              > Martin[/color]

              I don't know if I understand exactly, but based on what I /think/ you
              are doing, I would probably consider something like this:

              class FunctionObject
              {
              public:
              int operator()() = 0;
              virtual ~FunctionObject () {}
              };

              class MyClass
              {
              public:
              MyClass(Functio nObject &fo) : func(fo) {}
              int DoIt() { return func(); }

              private:
              FunctionObject &func;
              };


              Now you supply functions via FunctionObject classes and you can have as
              many as you need, plus you can add more later without modifying existing
              sources and without re-compiling everything. MyClass can also be made a
              base class (don't forget the add a virtual destructor) if that is
              necessary for your application (it's not entirely clear to me whether
              this was required for other reasons or if you intended to use it as part
              of the solution to the problem at hand).

              -Kevin
              --
              My email address is valid, but changes periodically.
              To contact me please use the address from a recent posting.

              Comment

              • Tim Walkenhorst

                #8
                Re: Defining a class on the fly

                > Naturally, I could write a new class for each object and then create a[color=blue]
                > new object of that class, but since I would only create one object of
                > each class, I would like to do something like this, which should create
                > a pointer to an object called Root, which is of an unnamed class derived
                > from MaxNode:[/color]

                Hi Martin,

                As far as I know, there are no unnamed classes in C++ as they are in
                java.
                However you can define new classes inside of a function/block. That
                doesn't safe you a lot coding, but it avoids cluttering your
                namespace.

                The following example is a little stripped down, but I'm sure you can
                expand it to your needs:

                #include <memory>

                class Base
                {
                public:
                virtual int foo()=0;
                virtual ~Base(){};
                };


                std::auto_ptr<B ase> createDerived()
                {
                class Derived:public Base {
                virtual int foo() {
                return 42;
                }
                };
                return std::auto_ptr<B ase>(new Derived);
                }


                // Best, Tim

                Comment

                • John Harrison

                  #9
                  Re: Defining a class on the fly


                  "Karl Heinz Buchegger" <kbuchegg@gasca d.at> wrote in message
                  news:3F33ACBB.D C8A7BDC@gascad. at...[color=blue]
                  >
                  >
                  > So your goal is to not have to write all those classes by hand.
                  > Well. Let the compiler do it. Seems like what you want is a templated
                  > class, which takes 2 functions as the template arguments.
                  >
                  > Unfortunately I am not good in templates, so I drop out right now.
                  > Anyone else?
                  >[/color]

                  Like this?

                  #include <iostream>
                  #include <string>

                  class Sensation {};
                  class Reward {};

                  class MaxNodeBase
                  {
                  public:
                  virtual ~MaxNodeBase() {};
                  void AddChild(MaxNod eBase* m );
                  std::string ToString();
                  private:
                  Sensation* previousSensati on;
                  Reward* previousReward;
                  };

                  template <bool (*term)(Sensati on*), float (*value)(Sensat ion*) >
                  class MaxNode : public MaxNodeBase
                  {
                  public:
                  bool IsTerminated( Sensation* s ) { return term(s); }
                  float ValueOf( Sensation* s ) { return value(s); }
                  };

                  bool a_term(Sensatio n*) { return false; }
                  bool b_term(Sensatio n*) { return true; }
                  float a_value(Sensati on*) { return 0.0; }
                  float b_value(Sensati on*) { return 1.0; }

                  int main()
                  {
                  Sensation s;
                  MaxNode<a_term, a_value> a_node;
                  MaxNode<b_term, b_value> b_node;
                  std::cout << a_node.ValueOf( &s) << ' ' << b_node.ValueOf( &s) << '\n';
                  }


                  Comment

                  Working...