[C++-sig] Overriding Virtual Functions

Nathan Stewart swarfrat at gmail.com
Thu Mar 18 04:53:17 CET 2010


I have a C++ class like so:

namespace Foo
{
   class TypeA {};
   class TypeB {};

   class Connection
   {
      template <class T> void Publish(const T&);
      virtual void OnEvent(const TypeA&) {}
      virtual void OnEvent(const TypeB&) {}
   };
}

I've exported it like so:

namespace
{
    class ConnectionWrap : public Foo::Connection, wrapper<Foo::Connection>
    {
        virtual void OnEvent(const TypeA& event)
        {
            if (override f = get_override("OnEvent_TypeA"))
            {
                f(event);
            } // no need to call Connection::OnEvent since it does nothing
        }

        virtual void OnEvent(const TypeB& event)
        {
            if (override f = get_override("OnEvent_TypeB"))
            {
                f(event);
            } // no need to call Connection::OnEvent since it does nothing
        }
    };
}

BOOST_PYTHON_MODULE(_mypywrap)
{
    class_<ConnectionWrap, boost::noncopyable>("Connection")
        .def("Publish", &ConnectionWrap::Publish<TypeA>)
        .def("Publish", &ConnectionWrap::Publish<TypeB>)
        ;
}

It compiles, imports, etc..  However if I remove .def("Publish",
&ConnectionWrap::Publish<TypeA>), and I try:

    import _mypywrap
    connection = _mypywrap.Connection() # ok
    connection.Publish(_mypywrap.TypeA()) # not ok but expected.

The error msg is "Connection.Publish(Connection, TypeA) did not match C++
signature:..."
and it dumps a list of signatures it knows about which would be
"publish(Foo::Connection {lvalue}, Foo::TypeB)"

if I instead do the following:
    connection.Publish(_mypywrap.TypeB())

I get a seg fault, looking at the stack trace shows it blew up in
get_override(char const*, _typeobject*) const, and if I go to that frame,
both arguments have been optimized out.

Whew. So my questions are:  (besides what am I doing wrong - unless that's
easier to answer)
In the first example where I did not export the first publish, it failed as
expected. However the namespaces are not consistent between the signature
attempted to match and the known signatures.  I'm puzzled by that, but I
suspect its just a formatting difference - since the second example actually
does call publish (which I know because the stack trace shows me it received
a message from the C++ class and blew up trying to jump the chasm back into
python land). Am I doing something wrong with the namespaces here, and is
that why my functions aren't visible?

In the second example... I know that the python function "OnEvent_TypeB"
hasn't been created.  I don't get why it blows up in get_override rather
than fails.  The other examples I've found indicate that I should be able to
use that mechanism to provide access to the base class virtual functions
which do have bodies. In fact, I'm running into this problem with my
ConnectionWrap class, not something derived from it. Does the override need
to exist, and if so, how can I accomplish this goal (of only overriding
behavior I want to implement)?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20100317/dc240bfc/attachment.html>


More information about the Cplusplus-sig mailing list