In binding a derived class must I also bind all parent classes to the root class? - pybind11

True or False
To bind a derived class in a C++ class hierarchy one must also bind all the parent classes on up to the root class.
I'm looking to bind a bunch of custom data types in a project I just started on and am looking to scope out the degree of work involved. I'm looking to bind a class that's 3 levels of derivation away from a root type.
Are there any rules of thumb for when one must also bind the parent classes to successfully bind the child classes?

False
Let us consider a simple example:
#include <string>
class Parent
{
public:
Parent() { m_name = "Parent"; }
std::string foo() { return m_name + "::foo"; }
virtual std::string bar() { return m_name + "::bar"; }
protected:
std::string m_name;
};
class Derived : public Parent
{
public:
Derived() { m_name = "Derived"; }
std::string bar() override { return m_name + "::bar (override)"; }
};
This you can bind the way you describe: bind the parent, the derived class will benefit from all the derived methods (you even don't have to bind the override):
#include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(example, m)
{
py::class_<Parent>(m, "Parent")
.def(py::init<>(), "Constructor description")
.def("foo", &Parent::foo, "Function description")
.def("bar", &Parent::bar, "Function description")
.def("__repr__", [](const Parent&) { return "<Parent>"; });
py::class_<Derived, Parent>(m, "Derived")
.def(py::init<>(), "Constructor description")
.def("__repr__", [](const Derived&) { return "<Derived>"; });
}
Indeed
import example
p = example.Parent()
print(p.foo())
print(p.bar())
d = example.Derived()
print(d.foo())
print(d.bar())
will print
Parent::foo
Parent::bar
Derived::foo
Derived::bar (override)
However, if you just want to bind one derived class (you don't care about the parent, nor about any of the other derived classes) you can also just bind the derived class you care about, without ever specifying the parent:
#include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(example, m)
{
py::class_<Derived>(m, "Derived")
.def(py::init<>(), "Constructor description")
.def("foo", &Derived::foo, "Function description")
.def("bar", &Derived::bar, "Function description")
.def("__repr__", [](const Derived&) { return "<Derived>"; });
}
Indeed
import example
d = example.Derived()
print(d.foo())
print(d.bar())
prints
Derived::foo
Derived::bar (override)
See the docs for reference.

Related

Using templates to rewrite polymorphic class to one single class (compile time polymorphism)

In my current code I use runtime polymorphism to create different subtypes of "light" from a LightBase class. The lighttypes however are already known at compile time (preprocessor picks the right variant). So I figured it is really not the right tool to do so as it is slow (vtable lookup for virtual getter functions) and could be already done at compile time. I just don't know how... could it be done with templates? I don't have too much experience in template programming so I don't know what is possible.
Essentially I want to instantiate a subclass of either type NormalLight or SpecialLight which have the same functions as LightBase but operate on a different set of constants:
class Color
{
Color(std::string color_name) : color_name_(color_name) { }
private:
std::string color_name_;
}
class LightBase {
public:
std::unique_ptr& GetInstance() { return instance_; }
protected:
const resolution;
std::array<Color, 0> = { };
// ..
private:
static std::unique_ptr<LightBase> instance_;
}
class NormalLight : public LightBase
{
protected:
const resolution = 9;
std::array<Color, 3> { Color("blue"), Color("red"), Color("purple") };
// ..
}
class SpecialLight : public LightBase
{
protected:
const resolution = 13;
std::array<Color, 3> { Color("yellow"), Color("magenta"), Color("orange") };
// ..
}
#if defined CONFIG_LIGHT_TYPE_NORMAL
std::unique_ptr<LightBase> LightBase::instance_ = std::unique_ptr<NormalLight>(new NormalLight());
#elif defined CONFIG_LIGHT_TYPE_SPECIAL
std::unique_ptr<LightBase> LightBase::instance_ = std::unique_ptr<SpecialLight>(new SpecialLight());
#endif
In a function I could conditionally check for a template parameter (I guess) but it's a class definition. Also, the thing should compile in C++11. Any ideas?

Why can't print any statement outside the method body in class in dart

class Car {
var name;
var model;
var cc;
Car(this.name, this.model, this.cc);
printAll() {
print(name);
print(model);
print(cc);
}
print(name); //Showing Error
}
void main() {
var obj = Car("Marcedes", "Class E", 5000);
obj.printAll();
}
Why i can't do any kind of operation outside the method body. The code generates error in compilation which given bellow. The code write in Dartpad.
Error in Compilation. The output show
Error compiling to JavaScript:
main.dart:1:7:
Error: The non-abstract class 'Car' is missing implementations for these members:
You have declared a method named print with a parameter called name but without a method body, i.e. an abstract method. In order to instantiate a class, Dart obviously has to know what the method body is, therefore you cannot instantiate an abstract class.
You need to do two things:
Because you have an abstract method, and abstract methods are only allowed in abstract classes, you need to mark Car as abstract.
You need to create a subclass of Car that overrides print with an implementation, and then instead instantiate that class.
Something like this:
abstract class Car {
var name;
var model;
var cc;
Car(this.name, this.model, this.cc);
printAll() {
print(name);
print(model);
print(cc);
}
print(name); // Abstract method `print` with no implementation
}
class ConcreteCar extends Car {
ConcreteCar(name, model, cc): super(name, model, cc);
#override
print(name) {
// Implementation of `print`
}
}
void main() {
var obj = ConcreteCar("Mercedes", "Class E", 5000);
obj.printAll();
}
Note: I left the implementation of print empty because I didn't understand the reason for the abstract print method and what the goal of the design is. But it should be trivial for you to fill out the missing pieces.

how to call member methods inside a wrapper class without repeating the method definition inside the wrapper class?

let's assume i have a wrapper class that embeds a single memeber:
class wrapper {
public:
Object obj;
// the rest ...
};
if the member variable obj has some methods, how can i call the member variable method without explicitly defining methods in the wrapper class like this?
class wrapper{
public:
void foo { obj.foo (); }
int bar (int x) {return obj.bar(x); }
};
i know this is doable in python, but how can i have the same functionality in c++?
ps- please note i don't want to inherit from the member class. this wouldn't't be a wrapper class by definition. i want to achieve this through composition instead.
There are a few ways to handle this. One would be to create a getter to return the wrapper object and another is to override the typecast operator:
class Object {
public:
void foo() {cout << "test" << endl;}
};
class wrapper {
protected:
Object obj;
public:
operator Object&() {return obj;}
Object& getObject() {return obj;}
};
void f(A& a) {
a.foo();
}
int main() {
wrapper w;
((Object)w).foo();
w.getObject().foo();
f(w);
return 0;
}
As you can see, the typecast operator requires you to cast the wrapper object, except when passing as a parameter to the function f().
Also, in your example you already have the obj member as public so it is exposed. You could just:
wrapper w;
w.obj.foo();
Here's a discussion on that: What good are public variables then?

Swift: how to understand dynamic method dispatching in init method?

I find that the dynamic method dispatching in init method of Swift is different from which in C++, can anyone explain why?
This is the demo code and its output:
In Swift:
class Object {
init() {
a()
}
func a() {
print("Object")
}
}
class SubObject: Object {
override init() {
}
override func a() {
print("SubObject")
}
}
let a = SubObject()
// output: SubObject
In C++:
class Object {
public:
Object() {
a();
}
virtual void a() {
std::cout << "Object" << std::endl;
}
};
class SubObject: public Object {
public:
SubObject() {
}
virtual void a() {
std::cout << "SubObject" << std::endl;
}
};
int main(int argc, const char * argv[]) {
SubObject s;
return 0;
}
// output: Object
As you can see, these code above write in Swift and C++ are nearly the same, but their output is quite different, while Swift seems that it finds the override method and called the derived one, the C++ still called the super's.
Here at LearnCpp, it says:
Do not call virtual functions from constructors or destructors Here’s another gotcha that often catches unsuspecting new programmers. You should not call virtual functions from constructors or destructors. Why?
Remember that when a Derived class is created, the Base portion is constructed first. If you were to call a virtual function from the Base constructor, and Derived portion of the class hadn’t even been created yet, it would be unable to call the Derived version of the function because there’s no Derived object for the Derived function to work on.
In C++, it will call the Base version instead.
A similar issue exists for destructors. If you call a virtual function in a Base class destructor, it will always resolve to the Base class version of the function, because the Derived portion of the class will already have been destroyed.

final interface implementation not recognized from interface base list

How can a method from the InterfaceBaseList be implemented in the current interface ? Example:
interface bar(T)
{
void method1(T a);
void method2(T a);
}
interface baz: bar!int
{
final void method1(int a){}
}
class foo: baz
{
this(){method1(0);}
void method2(int a){}
}
void main()
{
auto Foo = new foo;
Foo.method2(0);
}
outputs:
myfile.d(xx): Error: foo interface function 'void method1(int a)'
is not implemented
It seems that the compiler doesnt get that baz.method1 is actually bar.method1.
Note that the example illustrates that in baz, for some reasons, we know that method1 will always have the same implemtation. a baz implementer mays be down-casted as a bar (so making a dummy final method1 in bar is not possible).
Interfaces can only declare virtual members without implementation, or final members with implementation. Your code is attempting to override a virtual method with a non-virtual implementation. Due to the nature of interfaces, you cannot actually override anything within them. What you want instead is an abstract class.
abstract class baz: bar!int
{
override void method1(int a){}
}
Replacing your baz interface with the above class will clear up the issue.
As an example of why this isn't allowed, consider this code: (Does not compile, of course!)
interface Root {
int foo();
}
interface BranchA : Root {
override int foo() { return 1; }
}
interface BranchB : Root {
override int foo() { return 2; }
}
class C : BranchA, BranchB { }
What would (new C()).foo() return? The result is ambiguous. It is only acceptable to override the interface methods in a class, because unlike interfaces, you can only inherit one class at a time.