1

I've got a virtual base class:

class H{
    public:
    H(); // the implementation is in .cpp file, so this is not pure virtual
    virtual ~H();
    //... // other members
};

and the derived class:

class Hm : public H{
public:
 Hm(){ /*define constructor*/ }
...
   void method1();
};

I export two classes to Python using Boost.Python. Next, suppose there is another class X that contains a variable of type H:

class X{
public:     
 X(){ /*define constructor*/ }
 H  h;  // data member
 //...
};

The class and the variable h are also exposed to Python. Now, in Python I can do this:

x = X()  # construct the object x of type X
x.h = Hm()  # assign the data member of type H to the object of type Hm
            # no problem with that, because of the inheritance

Now, the problem is - how do i call method of the class Hm (method1) from x.h? The object x.h is of type H, which does not define method of derived class method1. So the call

x.h.method1()

gives the error

So, is there any way to do that? Or perhaps i need to change the design of classes. In the latter case, what would be the most optimal way for the type of utilization i'm trying to do in the above example?

user938720
  • 271
  • 3
  • 14
  • Is `method1` an implementation detail, or should it be part of the interface of `H`? – Peter Wood Jul 10 '15 at 21:25
  • @Peter, method1 is one of the methods of the derived class, but not the member of the base class – user938720 Jul 10 '15 at 21:54
  • I know what it is, but what is the intended design? Is it meant to be used by users of `H` or not. If it is it should be part of `H`'s interface, if not, `H` should delegate to it. – Peter Wood Jul 10 '15 at 22:43

1 Answers1

2

The behavior you are experiencing here is called slicing. "Slicing" is where you assign an object of a derived class to an instance of a base class, thereby losing part of the information - some of it is "sliced" away.

If you want to be able to call method1() you need either:

  • add Hm as a member to class X
  • add H* as a member to class Xand add virtual or pure virtual method1() to class H

Some ideas how to expose pointer to python: here and here

Community
  • 1
  • 1
doqtor
  • 8,414
  • 2
  • 20
  • 36
  • Hm as a member of class X - that is, of course, trivial, but not exactly what i want - imagine that there are many derived classes Hm1, Hm2, etc. one can define, but they all should be utilized according to general interface of class H (although H is not pure virtual, so by interface i don't mean that). I hope to have a generic handler of the base class, which would also work on derived classes after assignment. I tend to think that using the pointer to the base class may be a better solution, but not sure how to use it in Python – user938720 Jul 10 '15 at 22:01
  • ah, i see -so virtual method1() in base class - yes, this may be the solution, need to try – user938720 Jul 10 '15 at 22:03
  • 1
    But you still need H to be a pointer, otherwise `H::method1()` will be always called no matter if the object created was H or Hm. I added some links to my answer about exposing pointers to python which you may find helpful. – doqtor Jul 10 '15 at 22:11