blob: 082978b4efd900ceb6db0b022c7c179a38594bed [file] [log] [blame]
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -04001/*
2 example/example-inheritance.cpp -- inheritance, automatic upcasting for polymorphic types
3
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
10#include "example.h"
11
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") {}
26 void bark() const { std::cout << "Woof!" << std::endl; }
27};
28
29class Rabbit : public Pet {
30public:
31 Rabbit(const std::string &name) : Pet(name, "parrot") {}
32};
33
34void pet_print(const Pet &pet) {
35 std::cout << pet.name() + " is a " + pet.species() << std::endl;
36}
37
38void dog_bark(const Dog &dog) {
39 dog.bark();
40}
41
42
43struct BaseClass { virtual ~BaseClass() {} };
44struct DerivedClass1 : BaseClass { };
45struct DerivedClass2 : BaseClass { };
46
47void init_ex_inheritance(py::module &m) {
48 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
62 m.def("pet_print", pet_print);
63 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; });
72}