Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8615901
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T05:29:32+00:00 2026-06-12T05:29:32+00:00

I have a C++ class with a virtual method: //C++ class A { public:

  • 0

I have a C++ class with a virtual method:

//C++
class A
{

    public:
        A() {};
        virtual int override_me(int a) {return 2*a;};
        int calculate(int a) { return this->override_me(a) ;}

};

What I would like to do is to expose this class to Python with Cython, inherit from this class in Python and have the correct overridden called:

#python:
class B(PyA):
   def override_me(self, a):
       return 5*a
b = B()
b.calculate(1)  # should return 5 instead of 2

Is there a way to do this ?
Now I’m thinking, it could also be great if we could override the virtual method in Cython as well (in a pyx file), but allowing users to do this in pure python is more important.

Edit: If this helps, a solution could be to use the pseudocode given here: http://docs.cython.org/src/userguide/pyrex_differences.html#cpdef-functions

But there are two problems then :

  • I don’t know how to write this pseudocode in Cython
  • maybe there is a better approach
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-12T05:29:33+00:00Added an answer on June 12, 2026 at 5:29 am

    Excellent !

    Not complete but sufficient.
    I’ve been able to do the trick for my own purpose. Combining this post with the sources linked above.
    It’s not been easy, since I’m a beginner at Cython, but I confirm that it is the only way I could find over the www.

    Thanks a lot to you guys.

    I am sorry that I don’t have so much time go into textual details, but here are my files (might help to get an additional point of view on how to put all of this together)

    setup.py :

    from distutils.core import setup
    from distutils.extension import Extension
    from Cython.Distutils import build_ext
    
    setup(
        cmdclass = {'build_ext': build_ext},
        ext_modules = [
        Extension("elps", 
                  sources=["elps.pyx", "src/ITestClass.cpp"],
                  libraries=["elp"],
                  language="c++",
                  )
        ]
    )
    

    TestClass :

    #ifndef TESTCLASS_H_
    #define TESTCLASS_H_
    
    
    namespace elps {
    
    class TestClass {
    
    public:
        TestClass(){};
        virtual ~TestClass(){};
    
        int getA() { return this->a; };
        virtual int override_me() { return 2; };
        int calculate(int a) { return a * this->override_me(); }
    
    private:
        int a;
    
    };
    
    } /* namespace elps */
    #endif /* TESTCLASS_H_ */
    

    ITestClass.h :

    #ifndef ITESTCLASS_H_
    #define ITESTCLASS_H_
    
    // Created by Cython when providing 'public api' keywords
    #include "../elps_api.h"
    
    #include "../../inc/TestClass.h"
    
    namespace elps {
    
    class ITestClass : public TestClass {
    public:
        PyObject *m_obj;
    
        ITestClass(PyObject *obj);
        virtual ~ITestClass();
        virtual int override_me();
    };
    
    } /* namespace elps */
    #endif /* ITESTCLASS_H_ */
    

    ITestClass.cpp :

    #include "ITestClass.h"
    
    namespace elps {
    
    ITestClass::ITestClass(PyObject *obj): m_obj(obj) {
        // Provided by "elps_api.h"
        if (import_elps()) {
        } else {
            Py_XINCREF(this->m_obj);
        }
    }
    
    ITestClass::~ITestClass() {
        Py_XDECREF(this->m_obj);
    }
    
    int ITestClass::override_me()
    {
        if (this->m_obj) {
            int error;
            // Call a virtual overload, if it exists
            int result = cy_call_func(this->m_obj, (char*)"override_me", &error);
            if (error)
                // Call parent method
                result = TestClass::override_me();
            return result;
        }
        // Throw error ?
        return 0;
    }
    
    } /* namespace elps */
    

    EDIT2 : A note about PURE virtual methods (it appears to be a quite recurrent concern). As shown in the above code, in that particular fashion, “TestClass::override_me()” CANNOT be pure since it has to be callable in case the method is not overridden in the Python’s extended class (aka : one doesn’t fall in the “error”/”override not found” part of the “ITestClass::override_me()” body).

    Extension : elps.pyx :

    cimport cpython.ref as cpy_ref
    
    cdef extern from "src/ITestClass.h" namespace "elps" :
        cdef cppclass ITestClass:
            ITestClass(cpy_ref.PyObject *obj)
            int getA()
            int override_me()
            int calculate(int a)
    
    cdef class PyTestClass:
        cdef ITestClass* thisptr
    
        def __cinit__(self):
           ##print "in TestClass: allocating thisptr"
           self.thisptr = new ITestClass(<cpy_ref.PyObject*>self)
        def __dealloc__(self):
           if self.thisptr:
               ##print "in TestClass: deallocating thisptr"
               del self.thisptr
    
        def getA(self):
           return self.thisptr.getA()
    
    #    def override_me(self):
    #        return self.thisptr.override_me()
    
        cpdef int calculate(self, int a):
            return self.thisptr.calculate(a) ;
    
    
    cdef public api int cy_call_func(object self, char* method, int *error):
        try:
            func = getattr(self, method);
        except AttributeError:
            error[0] = 1
        else:
            error[0] = 0
            return func()
    

    Finally, the python calls :

    from elps import PyTestClass as TC;
    
    a = TC(); 
    print a.calculate(1);
    
    class B(TC):
    #   pass
        def override_me(self):
            return 5
    
    b = B()
    print b.calculate(1)
    

    This should make the previous linked work hopefully more straight to the point we’re discussing here…

    EDIT : On the other hand the above code could be optimized by using ‘hasattr’ instead of try/catch block :

    cdef public api int cy_call_func_int_fast(object self, char* method, bint *error):
        if (hasattr(self, method)):
            error[0] = 0
            return getattr(self, method)();
        else:
            error[0] = 1
    

    The above code, of course, makes a difference only in the case where we don’t override the ‘override_me’ method.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a base class: class motorcycle { public: virtual int speed() { return
I have a class: public class User { public virtual int Id { get;
i have situation like this: class IData { virtual void get() = 0; virtual
I would create an interface like that : class IMother { public: // This
I have a class: public abstract class AbstractDictionaryObject { public virtual int LangId {
I have two virtual classes I would like to wrap in boost python, I
I have an abstract class that has a virtual method. The method is virtual
I have this virtual method: const string& my_class::to_string() const { string str(this->name + string(
I have a the following method definition in my class: virtual Calc* Compile( Evaluator*
I have my class X : public class ClassX { public virtual IList<ClassY> ListY

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.