www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How do you return a subclass instance from a base class method?

reply Daniel Donnelly, Jr. <enjoysmath gmail.com> writes:
I have SubclassOf derived from PosetRelation.  For any poset 
relation, the transitivity law applies, however, I'd like to 
return the correct type:

```
    PosetRelation transitivity(PosetRelation R, PosetRelation S)
    {
       if (R.op == S.op)
       {
          if (R.right is S.left)
             return new SubclassOf(R.left, S.right);
       }

       return null;
    }

```

How does one accomplish this in D?  Because PosetRelation doesn't 
know about SubclassOf, in general.
Nov 16 2022
next sibling parent reply MorteFeuille123 <MorteFeuille123 mrt.rt> writes:
On Thursday, 17 November 2022 at 04:25:13 UTC, Daniel Donnelly, 
Jr. wrote:
 I have SubclassOf derived from PosetRelation.  For any poset 
 relation, the transitivity law applies, however, I'd like to 
 return the correct type:


 How does one accomplish this in D?  Because PosetRelation 
 doesn't know about SubclassOf, in general.
You can use TypeInfoClass: ```d class Base { } class Derived : Base { } Object newDerivedFromTi(Base b) { return typeid(b).create(); } void main(string[] args) { Base b = new Base; Base d = new Derived; assert(cast(Derived)newDerivedFromTi(d)); } ``` But that only works with default constructors, i.e no parameters. Another way is to define a virtual function in the Base: ```d class Base { Object createMostDerived(Base b1, Base b2) { return new typeof(this); } } class Derived : Base { override Object createMostDerived(Base b1, Base b2) { return new typeof(this); } } Object newDerivedFromTi(Base b) { return b.createMostDerived(b, b); } void main(string[] args) { Base b = new Base; Base d = new Derived; assert(cast(Derived)newDerivedFromTi(d)); } ``` assuming the PosetRelation (here called Base) actually cary the SubclassOf type (here called Derived).
Nov 16 2022
parent reply Daniel Donnelly, Jr. <enjoysmath gmail.com> writes:
On Thursday, 17 November 2022 at 05:21:05 UTC, MorteFeuille123 
wrote:
 On Thursday, 17 November 2022 at 04:25:13 UTC, Daniel Donnelly, 
 Jr. wrote:
 [...]
You can use TypeInfoClass: [...]
I don't get it - you never made use of b1 or b2...
Nov 16 2022
parent MorteFeuille123 <MorteFeuille123 mrt.rt> writes:
On Thursday, 17 November 2022 at 06:48:13 UTC, Daniel Donnelly, 
Jr. wrote:
 On Thursday, 17 November 2022 at 05:21:05 UTC, MorteFeuille123 
 wrote:
 On Thursday, 17 November 2022 at 04:25:13 UTC, Daniel 
 Donnelly, Jr. wrote:
 [...]
You can use TypeInfoClass: [...]
I don't get it - you never made use of b1 or b2...
yeah this was oversimplified on purpose, I did not realize that this coulmd be confusing. I dont know what you do with your constructor parameter either, would I say, as a second explanation.
Nov 17 2022
prev sibling next sibling parent Daniel Donnelly, Jr. <enjoysmath gmail.com> writes:
```
PosetRelation transitivity(PosetRelation R, PosetRelation S)
{
    // These if conditions are typically ordered from easiest to
    // most involved-to-check.
    if (R.op == S.op &&
        is(typeof(R) == typeof(S)) &&
        R.right == S.left)
    {
       return new typeof(R)(
          R.left, S.right,
          by("transitivity of " ~ R.op));     // Proof by this 
axiom
    }

    return null;
}
```

Not sure if that would work yet.  Have to test it.
Nov 16 2022
prev sibling next sibling parent reply zjh <fqbqrr 163.com> writes:
On Thursday, 17 November 2022 at 04:25:13 UTC, Daniel Donnelly, 
Jr. wrote:
 ...
`crtp`, will it work?
Nov 16 2022
parent Daniel Donnelly, Jr. <enjoysmath gmail.com> writes:
On Thursday, 17 November 2022 at 05:34:49 UTC, zjh wrote:
 On Thursday, 17 November 2022 at 04:25:13 UTC, Daniel Donnelly, 
 Jr. wrote:
 ...
`crtp`, will it work?
Can't use CRTP, because once you choose a derived class to pass into the template system, how do you pass in subclasses of that class and so on...
Nov 16 2022
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/16/22 11:25 PM, Daniel Donnelly wrote:
 I have SubclassOf derived from PosetRelation.  For any poset relation, 
 the transitivity law applies, however, I'd like to return the correct type:
 
 ```
     PosetRelation transitivity(PosetRelation R, PosetRelation S)
     {
        if (R.op == S.op)
        {
           if (R.right is S.left)
              return new SubclassOf(R.left, S.right);
        }
 
        return null;
     }
 
 ```
 
 How does one accomplish this in D?  Because PosetRelation doesn't know 
 about SubclassOf, in general.
I'd use a template: ```d T transitivity(T : PosetRelation)(T R, T S) { if (R.op == S.op) { if (R.right is S.left) return new T(R.left, S.right); } return null; } ``` -Steve
Nov 17 2022