blob: f43edc261fc885ed9950daecdde8290e8964cc81 [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
Jason Rhinelander6b52c832016-09-06 12:27:00 -040034class Hamster : public Pet {
35public:
36 Hamster(const std::string &name) : Pet(name, "rodent") {}
37};
38
Dean Moldovan665e8802016-08-12 22:28:31 +020039std::string pet_name_species(const Pet &pet) {
40 return pet.name() + " is a " + pet.species();
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -040041}
42
Dean Moldovan665e8802016-08-12 22:28:31 +020043std::string dog_bark(const Dog &dog) {
44 return dog.bark();
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -040045}
46
47
48struct BaseClass { virtual ~BaseClass() {} };
49struct DerivedClass1 : BaseClass { };
50struct DerivedClass2 : BaseClass { };
51
Jason Rhinelander52f4be82016-09-03 14:54:22 -040052test_initializer inheritance([](py::module &m) {
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -040053 py::class_<Pet> pet_class(m, "Pet");
54 pet_class
55 .def(py::init<std::string, std::string>())
56 .def("name", &Pet::name)
57 .def("species", &Pet::species);
58
59 /* One way of declaring a subclass relationship: reference parent's class_ object */
60 py::class_<Dog>(m, "Dog", pet_class)
61 .def(py::init<std::string>());
62
63 /* Another way of declaring a subclass relationship: reference parent's C++ type */
Wenzel Jakob8e5dceb2016-09-11 20:00:40 +090064 py::class_<Rabbit, Pet>(m, "Rabbit")
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -040065 .def(py::init<std::string>());
66
Jason Rhinelander6b52c832016-09-06 12:27:00 -040067 /* And another: list parent in class template arguments */
68 py::class_<Hamster, Pet>(m, "Hamster")
69 .def(py::init<std::string>());
70
Dean Moldovan665e8802016-08-12 22:28:31 +020071 m.def("pet_name_species", pet_name_species);
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -040072 m.def("dog_bark", dog_bark);
73
74 py::class_<BaseClass>(m, "BaseClass").def(py::init<>());
75 py::class_<DerivedClass1>(m, "DerivedClass1").def(py::init<>());
76 py::class_<DerivedClass2>(m, "DerivedClass2").def(py::init<>());
77
78 m.def("return_class_1", []() -> BaseClass* { return new DerivedClass1(); });
79 m.def("return_class_2", []() -> BaseClass* { return new DerivedClass2(); });
Jason Rhinelander0e489772016-09-11 18:41:28 -040080 m.def("return_class_n", [](int n) -> BaseClass* {
81 if (n == 1) return new DerivedClass1();
82 if (n == 2) return new DerivedClass2();
83 return new BaseClass();
84 });
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -040085 m.def("return_none", []() -> BaseClass* { return nullptr; });
Jason Rhinelander52f4be82016-09-03 14:54:22 -040086});