Thread overview
How to declare a virtual member (not a function) in a class
Feb 18, 2020
Adnan
Feb 18, 2020
Simen Kjærås
February 18, 2020
I have a base class that has a couple of constant member variables. These variables are abstract, they will only get defined when the derived class gets constructed.

class Person {
    const string name;
    const int id;
}

class Male : Person {
    this(string name = "Unnamed Male") {
        static int nextID = 0;
        this.id = nextID++;
        this.name = name;
    }
}

The compiler restricts me from assigning those two functions. How can I get around this?


February 18, 2020
On Tuesday, 18 February 2020 at 12:37:45 UTC, Adnan wrote:
> I have a base class that has a couple of constant member variables. These variables are abstract, they will only get defined when the derived class gets constructed.
>
> class Person {
>     const string name;
>     const int id;
> }
>
> class Male : Person {
>     this(string name = "Unnamed Male") {
>         static int nextID = 0;
>         this.id = nextID++;
>         this.name = name;
>     }
> }
>
> The compiler restricts me from assigning those two functions. How can I get around this?

const members can only be set in the constructor of the type that defines them. To set them in a subclass, forward the values to the superclass' constructor:

class Person {
    const string name;
    const int id;
    protected this(string _name, int _id) {
        id = _id;
        name = _name;
    }
}

class Male : Person {
    this(string name = "Unnamed Male") {
        static int nextID = 0;
        super(name, nextID++);
    }
}

--
  Simen
February 18, 2020
On Tuesday, 18 February 2020 at 12:37:45 UTC, Adnan wrote:
> I have a base class that has a couple of constant member variables. These variables are abstract, they will only get defined when the derived class gets constructed.
>
> class Person {
>     const string name;
>     const int id;
> }
>
> class Male : Person {
>     this(string name = "Unnamed Male") {
>         static int nextID = 0;
>         this.id = nextID++;
>         this.name = name;
>     }
> }
>
> The compiler restricts me from assigning those two functions. How can I get around this?

`const` members must be initialized by the same class that declares them. What you could do is have the abstract Person class declare a constructor (which would initialize the `const` members) and call it from derived class (such as `Male`) constructors by the `super(arg1, arg2)` syntax.

Alternatively, you could define `abstract` accessor functions in the base class and have the derived classes implement them. In D you can use the same syntax to call functions as if they were fields. (Before you had to put the @property attribute on such functions, but for the most part it is not necessary now.)