[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    [PyQt] sip: wrong class virtual function being called
From:       Jeremy Sanders <jeremy () jeremysanders ! net>
Date:       2015-06-05 17:34:46
Message-ID: 5571DDB6.3090302 () jeremysanders ! net
[Download RAW message or body]

Hi -

I'm having a problem with sip where the wrong version of a virtual 
function is being called. I'm overriding a virtual function in a python 
subclass of a C++ class. This function is being called by a C++ 
container, which owns the class instance. If I keep a Python reference 
to the instance, then everything works.

Please see the attached code. test.py calls the C++ code. Normally the 
code prints

Object::func()
42

If del in test.py is uncommented, then it prints

Object::func()
Object::func()

Therefore the inherited virtual function is being called, not the 
overriding function.

Is this a problem with my code, or a SIP bug? I'm using SIP 4.16.3 (on 
Ubuntu x86-64). Is there a workaround? I can change the C++ code.

Thanks

Jeremy

["test.py" (text/x-python)]

import mytest

cont = mytest.Scene()

obj1 = mytest.Object()
cont.root.addObject(obj1)

class NewObject(mytest.Object):
    def func(self):
        print(42)

obj2 = NewObject()
cont.root.addObject(obj2)
# uncomment below and 42 is not printed
# del obj2

cont.root.callFuncs()

["mytest.sip" (text/plain)]

%Module(name=mytest, version=0)

class Object
{
%TypeHeaderCode
#include <mytest.h>
%End
  public:
   virtual ~Object();
   virtual void func();
};

class ObjectContainer : public Object
{
%TypeHeaderCode
#include <mytest.h>
%End
 public:
  ~ObjectContainer();
  void addObject(Object* obj /Transfer/);
  void callFuncs();
};

class Scene
{
%TypeHeaderCode
#include <mytest.h>
%End

 public:
  Scene();
  ObjectContainer root;
};

["mytest.cpp" (text/x-c++src)]

#include <iostream>
#include "mytest.h"

Object::~Object()
{
}

void Object::func()
{
  std::cout << "Object::func()\n";
}

ObjectContainer::~ObjectContainer()
{
  for(unsigned i=0; i<objects.size(); ++i)
    delete objects[i];
}

void ObjectContainer::addObject(Object* obj)
{
  objects.push_back(obj);
}


void ObjectContainer::callFuncs()
{
  for(unsigned i=0; i<objects.size(); ++i)
    objects[i]->func();
}

Scene::Scene()
{
}

["mytest.h" (text/x-chdr)]

#ifndef MYTEST_H
#define MYTEST_H

#include <vector>

class Object
{
  public:
   virtual ~Object();
   virtual void func();
};

class ObjectContainer : public Object
{
 public:
  ~ObjectContainer();
  void addObject(Object* obj);
  void callFuncs();

 private:
  std::vector<Object*> objects;
};

class Scene
{
 public:
  Scene();
  ObjectContainer root;
};

#endif

[Attachment #7 (text/plain)]

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic