digitalmars.D.learn - Virtual functions and inheritance
- David Monagle (24/24) Jan 26 2015 Hi guys,
- H. S. Teoh via Digitalmars-d-learn (19/48) Jan 26 2015 Try this:
- David Monagle (2/2) Jan 26 2015 I can certainly work with that. Thank you very much! (and for
- Daniel =?UTF-8?B?S296w6Fr?= via Digitalmars-d-learn (17/48) Jan 27 2015 V Tue, 27 Jan 2015 04:38:57 +0000
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (12/26) Jan 27 2015 OTOH:
- Baz (24/38) Jan 27 2015 Could 'this T' be used for a static constructor ?
- bearophile (4/5) Jan 27 2015 I suggest to read some D documentation first, and program later.
- Tobias Pankrath (10/27) Jan 27 2015 I think it's a bug that you can use a template this parameter
- Baz (20/45) Jan 29 2015 This is almost the same code as written initially,
- Baz (17/17) Jan 29 2015 even more weird:
- Tobias Pankrath (2/21) Jan 29 2015 Because to!string calls toString, which is a virtual function.
Hi guys, I'm a former C++ developer and really enjoying working with D now. I have a question that I hope some of you may be able to answer. class Parent { property string typeName() { return typeof(this).stringof; } } class Child : Parent { } void main() { auto p = new Parent; auto c = new Child; assert(p.typeName == "Parent"); assert(p.typeName == "Child"); } I'm looking for an explanation as to why this doesn't work, then a suggestion for how I may achieve child classes being able to generate a string description of their own type, without redefining the typeName property on each child. (I'm currently solving this with a mixin, but I was hoping for a better solution. I'm assuming it doesn't work because either typeof(this) or .stringof is evaluated at compile time?
Jan 26 2015
On Tue, Jan 27, 2015 at 04:38:57AM +0000, David Monagle via Digitalmars-d-learn wrote:Hi guys, I'm a former C++ developer and really enjoying working with D now. I have a question that I hope some of you may be able to answer. class Parent { property string typeName() { return typeof(this).stringof; } }Try this: class Parent { property string typeName() { return typeid(this).toString(); } }class Child : Parent { } void main() { auto p = new Parent; auto c = new Child; assert(p.typeName == "Parent"); assert(p.typeName == "Child");Bug: the second assert should have c.typeName. :-) But I got what you mean.} I'm looking for an explanation as to why this doesn't work, then a suggestion for how I may achieve child classes being able to generate a string description of their own type, without redefining the typeName property on each child. (I'm currently solving this with a mixin, but I was hoping for a better solution. I'm assuming it doesn't work because either typeof(this) or .stringof is evaluated at compile time?typeof(this) is evaluated at compile-time. To get runtime information, you need to use typeid(). Of course, with my suggested change your code still won't work as-is, because typeid().toString() returns a fully-qualified name, so if your source file is test.d, it would return "test.Parent" and "test.Child". But you should be able to work with that. :-) T -- The volume of a pizza of thickness a and radius z can be described by the following formula: pi zz a. -- Wouter Verhelst
Jan 26 2015
I can certainly work with that. Thank you very much! (and for pointing out my typo in the example)
Jan 26 2015
V Tue, 27 Jan 2015 04:38:57 +0000 David Monagle via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> napsáno:Hi guys, I'm a former C++ developer and really enjoying working with D now. I have a question that I hope some of you may be able to answer. class Parent { property string typeName() { return typeof(this).stringof; } } class Child : Parent { } void main() { auto p = new Parent; auto c = new Child; assert(p.typeName == "Parent"); assert(p.typeName == "Child"); } I'm looking for an explanation as to why this doesn't work, then a suggestion for how I may achieve child classes being able to generate a string description of their own type, without redefining the typeName property on each child. (I'm currently solving this with a mixin, but I was hoping for a better solution. I'm assuming it doesn't work because either typeof(this) or .stringof is evaluated at compile time?You can use this T: class Parent { property string typeName(this T)() { return T.stringof; } } class Child : Parent { } void main() { auto p = new Parent; auto c = new Child; assert(p.typeName == "Parent"); assert(c.typeName == "Child"); }
Jan 27 2015
On Tuesday, 27 January 2015 at 08:19:46 UTC, Daniel Kozák wrote:You can use this T: class Parent { property string typeName(this T)() { return T.stringof; } } class Child : Parent { } void main() { auto p = new Parent; auto c = new Child; assert(p.typeName == "Parent"); assert(c.typeName == "Child"); }OTOH: void main() { auto p = new Parent; auto c = new Child; assert(p.typeName == "Parent"); assert(c.typeName == "Child"); p = c; assert(p.typeName == "Parent"); } It will still use the static type of the object that it's called on, not the dynamic type.
Jan 27 2015
On Tuesday, 27 January 2015 at 08:19:46 UTC, Daniel Kozák wrote:You can use this T: class Parent { property string typeName(this T)() { return T.stringof; } } class Child : Parent { } void main() { auto p = new Parent; auto c = new Child; assert(p.typeName == "Parent"); assert(c.typeName == "Child"); }Could 'this T' be used for a static constructor ? ----- class Bar { static T construct(this T, A...)(A a) { return new T(a); } } ---- doesn't work. And similarly to the the orginal post: ----- class Bar { static typeof(this) construct(A...)(A a) { return new typeof(this)(a); } } class Foo: Bar{} Foo foo= Foo.construct; // fail ---- construct() won't be redefined in the Bar descendants.
Jan 27 2015
Baz:doesn't work. And similarly to the the orginal post:I suggest to read some D documentation first, and program later. Bye, bearophile
Jan 27 2015
----- class Bar { static T construct(this T, A...)(A a) { return new T(a); } } ----I think it's a bug that you can use a template this parameter (this T) on a static member function without a direct compilation error.----- class Bar { static typeof(this) construct(A...)(A a) { return new typeof(this)(a); } }Because it's exactly the same to write it as static Bar construct(A...)(A a) { return new Bar(a); } Of course this does not work. I don't know how to do it without one line of boilerplate per class or without supplying the type via template argument. std.container.util : make takes the type to construct as an argument, but std.container do not form a class hierarchy.
Jan 27 2015
On Tuesday, 27 January 2015 at 04:38:59 UTC, David Monagle wrote:Hi guys, I'm a former C++ developer and really enjoying working with D now. I have a question that I hope some of you may be able to answer. class Parent { property string typeName() { return typeof(this).stringof; } } class Child : Parent { } void main() { auto p = new Parent; auto c = new Child; assert(p.typeName == "Parent"); assert(p.typeName == "Child"); } I'm looking for an explanation as to why this doesn't work, then a suggestion for how I may achieve child classes being able to generate a string description of their own type, without redefining the typeName property on each child. (I'm currently solving this with a mixin, but I was hoping for a better solution. I'm assuming it doesn't work because either typeof(this) or .stringof is evaluated at compile time?This is almost the same code as written initially, let somone explain why the hell this is working: --- module test; import std.conv; class Parent { property final string typeName() { return to!string(this); } } class Child : Parent { } void main() { auto p = new Parent; auto c = new Child; assert(p.typeName == __MODULE__ ~ ".Parent"); assert(c.typeName == __MODULE__ ~ ".Child"); } ---
Jan 29 2015
even more weird: --- module test; import std.conv; interface Meh{ final string typeName() {return to!string(this);} } class Parent : Meh {} class Child : Parent {} void main() { auto p = new Parent; auto c = new Child; assert(p.typeName == __MODULE__ ~ ".Parent"); assert(c.typeName == __MODULE__ ~ ".Child"); } ---
Jan 29 2015
This is almost the same code as written initially, let somone explain why the hell this is working: --- module test; import std.conv; class Parent { property final string typeName() { return to!string(this); } } class Child : Parent { } void main() { auto p = new Parent; auto c = new Child; assert(p.typeName == __MODULE__ ~ ".Parent"); assert(c.typeName == __MODULE__ ~ ".Child"); } ---Because to!string calls toString, which is a virtual function. It's the same as the NVI-Idiom in C++.
Jan 29 2015