digitalmars.D.learn - Q: How to return sub class from base class method
- Myron Alexander (9/33) Jun 17 2007 The method chain fails as doSomething returns type A.
- Jari-Matti =?ISO-8859-1?Q?M=E4kel=E4?= (17/44) Jun 17 2007 Yes, you can use CRTP
- Myron Alexander (8/28) Jun 17 2007 Thanks for the suggestion. I am hoping for a solution that does not
- Kirk McDonald (16/68) Jun 17 2007 I believe B should look like this, if you're using that pattern:
- Jari-Matti =?ISO-8859-1?Q?M=E4kel=E4?= (10/41) Jun 17 2007 Actually no - class B was supposed to be in the middle of the hierarchy ...
- Myron Alexander (9/55) Jun 18 2007 Thanks all.
Hello. I have a class structure as such:class A { typeof(this) doSomething (????) { ... return this; } } class B : A { typeof(this) doSomethingElse (????) { ... return this; } } void main () { // Fails B b = (new B()).doSomething (???).doSomethingElse (???); }The method chain fails as doSomething returns type A. I want to define method doSomething in such a way that it will return the specialized type (B) rather than the base type. I'm currently using a mixin to mixin overriding code:template doSomethingOverride () { override typeof(this) doSomething (????) { super.doSomething (????); return this; } }Is there a way to set the return type as the type instantiated? Thanks, Myron.
Jun 17 2007
Myron Alexander wrote:I have a class structure as such:Yes, you can use CRTP (http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern). class A(T) { T doSomething() { ... return cast(T)this; } } class B(T) : A!(T) { T doSomethingElse() { ... return cast(T)this; } } There might be other (more clever) ways to do this too. Like a mixin for the "selftype" or something.class A { typeof(this) doSomething (????) { ... return this; } } class B : A { typeof(this) doSomethingElse (????) { ... return this; } } void main () { // Fails B b = (new B()).doSomething (???).doSomethingElse (???); }The method chain fails as doSomething returns type A. I want to define method doSomething in such a way that it will return the specialized type (B) rather than the base type. Is there a way to set the return type as the type instantiated?
Jun 17 2007
Jari-Matti Mäkelä wrote:Yes, you can use CRTP (http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern). class A(T) { T doSomething() { ... return cast(T)this; } } class B(T) : A!(T) { T doSomethingElse() { ... return cast(T)this; } } There might be other (more clever) ways to do this too. Like a mixin for the "selftype" or something.Thanks for the suggestion. I am hoping for a solution that does not require me to set a type on instantiation. I just want to write: B b = (new B()).doSomething (???).doSomethingElse (???); If the language does not have a way to do it, that's ok, the mixin solution works. Regards, Myron.
Jun 17 2007
Jari-Matti Mäkelä wrote:Myron Alexander wrote:I believe B should look like this, if you're using that pattern: class B : A!(B) { B doSomethingElse() { // ... return this; } } Thus, B is derived from a class template to which you pass B as a parameter. This is often used in C++ as a way of emulating mixin-like behavior. Thus, D's template mixins could very well be a better solution. -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.orgI have a class structure as such:Yes, you can use CRTP (http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern). class A(T) { T doSomething() { ... return cast(T)this; } } class B(T) : A!(T) { T doSomethingElse() { ... return cast(T)this; } } There might be other (more clever) ways to do this too. Like a mixin for the "selftype" or something.class A { typeof(this) doSomething (????) { ... return this; } } class B : A { typeof(this) doSomethingElse (????) { ... return this; } } void main () { // Fails B b = (new B()).doSomething (???).doSomethingElse (???); }The method chain fails as doSomething returns type A. I want to define method doSomething in such a way that it will return the specialized type (B) rather than the base type. Is there a way to set the return type as the type instantiated?
Jun 17 2007
Kirk McDonald wrote:Jari-Matti Mäkelä wrote:Actually no - class B was supposed to be in the middle of the hierarchy so class C would have looked like that :) Something like class A(T = A) { ... } class B(T = B) : A!(T) { ... } would have been nice for those non-abstract base classes so they could have been instantiated too, but apparently the compiler didn't want to co-operate this time.class A(T) { T doSomething() { ... return cast(T)this; } } class B(T) : A!(T) { T doSomethingElse() { ... return cast(T)this; } } There might be other (more clever) ways to do this too. Like a mixin for the "selftype" or something.I believe B should look like this, if you're using that pattern: class B : A!(B) { B doSomethingElse() { // ... return this; } }Thus, B is derived from a class template to which you pass B as a parameter. This is often used in C++ as a way of emulating mixin-like behavior. Thus, D's template mixins could very well be a better solution.Feel free to create a better solution :)
Jun 17 2007
Jari-Matti Mäkelä wrote:Kirk McDonald wrote:Thanks all. I am happy with the mixin solution, even if I forget to add the mixin, the compiler will generate an error when I try to chain the class methods after the doSomething so it's not a dangerous one at that. Just for your information, I attached the test source where I am using it. The doSomething method here is called 'initCause'. Regards, Myron.Jari-Matti Mäkelä wrote:Actually no - class B was supposed to be in the middle of the hierarchy so class C would have looked like that :) Something like class A(T = A) { ... } class B(T = B) : A!(T) { ... } would have been nice for those non-abstract base classes so they could have been instantiated too, but apparently the compiler didn't want to co-operate this time.class A(T) { T doSomething() { ... return cast(T)this; } } class B(T) : A!(T) { T doSomethingElse() { ... return cast(T)this; } } There might be other (more clever) ways to do this too. Like a mixin for the "selftype" or something.I believe B should look like this, if you're using that pattern: class B : A!(B) { B doSomethingElse() { // ... return this; } }Thus, B is derived from a class template to which you pass B as a parameter. This is often used in C++ as a way of emulating mixin-like behavior. Thus, D's template mixins could very well be a better solution.Feel free to create a better solution :)
Jun 18 2007