Miles
Miles

Reputation: 2537

Boost Python Inheriting from Pure Virtual Class

When using a derived class from a pure virtual class in a Boost Python module, I am receiving the following error:

allocating an object of abstract class type

Without the Boost Python module, the error is not present. In the following example(close to my use case), what would be the issue? Do I have to make Python aware of the inheritance relationship between Base and Derived?

PythonMinimal.cpp

#include <boost/python.hpp>
#include <vector>
using namespace boost::python;

//Base class - pure virtual.
template<typename T>
class Base{
public:
virtual void foo() = 0;
};

//Derived class, inherites from Base.
template<typename T>
class Derived : public Base<T>{
public:
    Derived(int a, int b){
        //Do something.
    }

    void foo(){
        //Do something else.
    }
};

//Test class, uses instances of Derived stored in STL container of Base.
template<typename T>
class TestClass{
public:
    std::vector< Base<T> > vec;

    TestClass(int a, int b){
        vec.push_back(Derived<T>(a, b));
    }

    void foo(){
        vec.at(0).foo();
    }
};

//Build python module.
BOOST_PYTHON_MODULE(cpuMLP){
    class_< TestClass<float> >("TestClass", init<int, int>())
        .def("foo", &TestClass<float>::foo);
};

CMakeLists.txt

#Set CMake Version and project name.
cmake_minimum_required(VERSION 2.8)
project(PythonMinimal)

#Attempt to find Python and Boost Python.
find_package(PythonInterp)
find_package(PythonLibs)
find_package(Boost COMPONENTS python)

#Find includes.
include_directories(${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})

#Add library to project.
add_library(PythonMinimal SHARED PythonMinimal.cpp)
target_link_libraries(PythonMinimal ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})

Upvotes: 1

Views: 201

Answers (1)

Barry
Barry

Reputation: 303840

This isn't related to python at all (you're not exposing either Base or Derived to python), the problem is in your vector:

std::vector< Base<T> > vec;

Base<T> is an abstract class that you're holding values of. That isn't going to work. You need to store them by pointer:

std::vector<std::unique_ptr<Base<T>>> vec;

This way you're not slicing your Derived<T> objects.

Upvotes: 2

Related Questions