Thread overview | |||||
---|---|---|---|---|---|
|
August 13, 2017 C++ linkage specifics WRT virtual vs non-virtual member functions | ||||
---|---|---|---|---|
| ||||
I'm writing some bindings and have run in to a dilemma due to the lack of explicit information on how the D compiler "decides" to use virtual dispatch for a member function or not. Specifically, I have a C++ library that _explicitly_ marks some member functions as virtual, in addition to a plethora of non-virtual functions. I would like to be certain that the D compiler understands that I would like it to treat those functions as virtual functions, but unlike C++ where there is a `virtual` classifier for functions, D does not appear to have such a facility. The C++ interop documentation suggests that both non- and virtual functions are supported, but further suggests that it only treats inherited functions as virtual with no method of explicitly requesting virtual dispatch for that method. As far as I can tell, all specified member functions in a class with C++ linkage are assumed to be non-virtual unless they are overriden? |
August 13, 2017 Re: C++ linkage specifics WRT virtual vs non-virtual member functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman Hargrave | On Sunday, 13 August 2017 at 07:18:31 UTC, Roman Hargrave wrote:
> I'm writing some bindings and have run in to a dilemma due to the lack of explicit information on how the D compiler "decides" to use virtual dispatch for a member function or not.
>
> Specifically, I have a C++ library that _explicitly_ marks some member functions as virtual, in addition to a plethora of non-virtual functions.
>
> I would like to be certain that the D compiler understands that I would like it to treat those functions as virtual functions, but unlike C++ where there is a `virtual` classifier for functions, D does not appear to have such a facility.
>
> The C++ interop documentation suggests that both non- and virtual functions are supported, but further suggests that it only treats inherited functions as virtual with no method of explicitly requesting virtual dispatch for that method.
>
> As far as I can tell, all specified member functions in a class with C++ linkage are assumed to be non-virtual unless they are overriden?
W.r.t. virtual member functions, D's syntax is more similar to Java than to C++, in that class member functions are virtual by default, unless marked as `final`.
So to declare the following C++ class:
class Base
{
virtual int fun();
int gun();
};
In D you have to do the following:
extern (C++) class Base
{
int fun();
final int gun();
}
Like all other attributes, you can group multiple members to which you want to apply the `final` attribute by either:
class C
{
final
{
int gun();
int hun();
}
}
Or:
class C
{
final:
int gun();
int hun();
}
Though be aware that unlike the protection attributes (public, private), there's no way to undo 'final:', so if you use it, you would have to move it with all the non-virtual methods to the bottom of the class definition.
|
August 13, 2017 Re: C++ linkage specifics WRT virtual vs non-virtual member functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman Hargrave | On 13.08.2017 09:18, Roman Hargrave wrote: > I'm writing some bindings and have run in to a dilemma due to the lack of explicit information on how the D compiler "decides" to use virtual dispatch for a member function or not. > > Specifically, I have a C++ library that _explicitly_ marks some member functions as virtual, in addition to a plethora of non-virtual functions. > > I would like to be certain that the D compiler understands that I would like it to treat those functions as virtual functions, but unlike C++ where there is a `virtual` classifier for functions, D does not appear to have such a facility. > ... You can create one (this will look nicer with static foreach): struct virtual{} mixin template CheckVirtual(T){ import std.traits: isFinal, hasUDA; mixin({string r=""; foreach(m;__traits(allMembers,T)){ r~=`static assert(isFinal!(T.`~m~`)||hasUDA!(T.`~m~`,virtual),"'`~T.stringof~`.`~m~`' is neither final nor @virtual");`; r~=`static assert(!isFinal!(T.`~m~`)||!hasUDA!(T.`~m~`,virtual),"'`~T.stringof~`.`~m~`' is both final and @virtual");`; } return r;}()); } // example: extern(C++) class C{ final void foo(){} // ok @virtual void bar(){} // ok void baz(){} // Error: static assert "'C.baz' is neither final not @virtual" @virtual final void qux(){} // Error: static assert "'C.qux' is both final and @virtual" } mixin CheckVirtual!C; > The C++ interop documentation suggests that both non- and virtual functions are supported, but further suggests that it only treats inherited functions as virtual with no method of explicitly requesting virtual dispatch for that method. > > As far as I can tell, all specified member functions in a class with C++ linkage are assumed to be non-virtual unless they are overriden? All member functions are virtual by default. Only member functions explicitly marked as `final` are not virtual. The code above makes both explicit to help prevent mistakes. |
Copyright © 1999-2021 by the D Language Foundation