blob: e1aad9920151dce3b7a78185b62b62c0f0ae3252 [file] [log] [blame]
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -04001/*
Dean Moldovana0c1ccf2016-08-12 13:50:00 +02002 tests/test_inheritance.cpp -- inheritance, automatic upcasting for polymorphic types
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -04003
4 Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
5
6 All rights reserved. Use of this source code is governed by a
7 BSD-style license that can be found in the LICENSE file.
8*/
9
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020010#include "pybind11_tests.h"
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -040011
12class Pet {
13public:
14 Pet(const std::string &name, const std::string &species)
15 : m_name(name), m_species(species) {}
16 std::string name() const { return m_name; }
17 std::string species() const { return m_species; }
18private:
19 std::string m_name;
20 std::string m_species;
21};
22
23class Dog : public Pet {
24public:
25 Dog(const std::string &name) : Pet(name, "dog") {}
Dean Moldovan665e8802016-08-12 22:28:31 +020026 std::string bark() const { return "Woof!"; }
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -040027};
28
29class Rabbit : public Pet {
30public:
31 Rabbit(const std::string &name) : Pet(name, "parrot") {}
32};
33
Dean Moldovan665e8802016-08-12 22:28:31 +020034std::string pet_name_species(const Pet &pet) {
35 return pet.name() + " is a " + pet.species();
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -040036}
37
Dean Moldovan665e8802016-08-12 22:28:31 +020038std::string dog_bark(const Dog &dog) {
39 return dog.bark();
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -040040}
41
42
43struct BaseClass { virtual ~BaseClass() {} };
44struct DerivedClass1 : BaseClass { };
45struct DerivedClass2 : BaseClass { };
46
Jason Rhinelander52f4be82016-09-03 14:54:22 -040047test_initializer inheritance([](py::module &m) {
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -040048 py::class_<Pet> pet_class(m, "Pet");
49 pet_class
50 .def(py::init<std::string, std::string>())
51 .def("name", &Pet::name)
52 .def("species", &Pet::species);
53
54 /* One way of declaring a subclass relationship: reference parent's class_ object */
55 py::class_<Dog>(m, "Dog", pet_class)
56 .def(py::init<std::string>());
57
58 /* Another way of declaring a subclass relationship: reference parent's C++ type */
59 py::class_<Rabbit>(m, "Rabbit", py::base<Pet>())
60 .def(py::init<std::string>());
61
Dean Moldovan665e8802016-08-12 22:28:31 +020062 m.def("pet_name_species", pet_name_species);
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -040063 m.def("dog_bark", dog_bark);
64
65 py::class_<BaseClass>(m, "BaseClass").def(py::init<>());
66 py::class_<DerivedClass1>(m, "DerivedClass1").def(py::init<>());
67 py::class_<DerivedClass2>(m, "DerivedClass2").def(py::init<>());
68
69 m.def("return_class_1", []() -> BaseClass* { return new DerivedClass1(); });
70 m.def("return_class_2", []() -> BaseClass* { return new DerivedClass2(); });
71 m.def("return_none", []() -> BaseClass* { return nullptr; });
Jason Rhinelander52f4be82016-09-03 14:54:22 -040072});