On Thu, Jul 24, 2025 at 05:19:17PM +0000, Andy Valencia via Digitalmars-d-learn 
wrote:
> What is considered the "clean" way to address this error:
> 
> ```
> tst60.d(7): Error: class `tst60.B` cannot implicitly generate a
> default constructor when base class `tst60.A` is missing a default
> constructor
> ```

Your base class does not have a default constructor.  The only
constructor it has takes a parameter `int val`.  This means derived
classes need to invoke `super(...)` and provide an argument for `val`,
since there's no way the compiler can divine what's the correct value to
pass to the base class constructor if you don't specify what it should
be.

If there is a default value that you wish to use when none are
specified, either provide a default constructor that sets `val` to the
default value, or specify a default value.


> Yes, this is a toy example, but it reflects something I'm doing in
> actual code.  The subclass has no state, thus it's fine to let the
> superclass take care of initialization.  Do I really need a shim like
> this:
> 
> ```d
>     this(int val) {
>         super(val);
>     }
> ```

In D, constructors are not inherited, so yes, unfortunately you have to
write a forwarding ctor that passes the arguments along to the base
class.  If you find this to be too much boilerplate, there are ways of
using metaprogramming to automate it.  I believe code.dlang.org has a
package or two that provides this, or you can write something yourself.

Here's an example of how to do it (caveat: I threw this together in ~5
mins, so there's probably lots of room for improvement):

```
import std;

/**
 * Automatically inject ctors that take the same arguments as base class ctors,
 * and forwards them to the respective base class ctor.
 */
mixin template ForwardBaseCtors() {
        static foreach (Base; BaseClassesTuple!(typeof(this))) {
                static foreach (func; MemberFunctionsTuple!(Base, "__ctor")) {
                        this(Parameters!func args) {
                                super(args);
                        }
                }
        }
}

// Here's your base class
class B {
        // Here's a non-default ctor
        this(int val, string s, float f) { }
}

// Here's your derived class
class D : B {
        // Note: derived class ctor not explicitly specified here
        mixin ForwardBaseCtors;
}

void main() {
        // Voila!  The base class ctor got (semi-)automatically forwarded!
        B obj = new D(123, "abc", 3.14159);
}
```

Hope this helps.


T

-- 
What do you call someone who steals energy from the museum?  A Joule thief.

Reply via email to