Waarom is OpAssign niet overbelastbaar voor klassen?

This table says that assignment overloading is only possible for structs, not classes. This surprises me. Isn't the syntactic sugar of A = B harmless? What was the design rationale for restricting it to structs?

3

3 antwoord

In D worden klassen gebruikt door verwijzing. Dus wanneer u A = B doet, kopieert u het object zelf niet, maar alleen een verwijzing naar dat object.

Geen van de objecten wordt tijdens het proces gewijzigd. Het heeft dus geen zin om opAssign voor thoses te definiëren.

8
toegevoegd

D-klassen hebben referentiesemantiek. Als u een manier wilt om een ​​kopie van het object te krijgen (het denkt), is het standaard of conventioneel wat u moet doen een .dup -eigenschap.

4
toegevoegd
@JonathanMDavis: standaard zoals in normaal, niet standaard zoals in ISO. :O)
toegevoegd de auteur BCS, de bron
A a = nieuwe A (); a = nieuw A (a); of A a = nieuw A (); a = a.dup; (als het type dit ondersteunt).
toegevoegd de auteur BCS, de bron
Dit maakt gebruik van het postblit, dat u in deze klasse kunt definiëren met dit (dit) {}. Het is post-blit, dus alle variabelen zijn gekopieerd, je hoeft alleen maar te werken aan de pointervariabelen in de klas. Door ze bijvoorbeeld te duperen.
toegevoegd de auteur Taco de Wolff, de bron
Dus een kopie-constructor ziet er als volgt uit: klasse A {this (A a) {}}? Het maakt wel een duidelijk onderscheid tussen toewijzing en constructie syntaxis. Sorry voor de verkeerde informatie!
toegevoegd de auteur Taco de Wolff, de bron
Ik geloof niet dat er op dit moment echt een standaard bestaat, maar .dup zou een veel gebruikte manier zijn om dit te doen, en als we doen beslissen over een echte standaard, dan zou dat de waarschijnlijke keuze zijn.
toegevoegd de auteur Jonathan M Davis, de bron
@BCS Ik bedoelde standaard zoals in het algemeen eens is geworden dat dit de manier is om het te doen. Ik denk niet dat het zelfs noodzakelijkerwijs iets is dat de meerderheid van de D-gebruikers doet. Het komt vaak voor, en als er een algemene overeenkomst bereikt zou moeten worden, dan is de kans groot dat dat het geval is, maar AFAIK is er momenteel geen dergelijke algemene overeenkomst.
toegevoegd de auteur Jonathan M Davis, de bron
@Daevius-klassen hebben geen postplit-constructors. Ze zijn voor structs, geen klassen. Er is geen ingebouwde manier om de inhoud van een klasse te kopiëren. Je moet een functie aanmaken die een kopie retourneert of een copy-constructor maakt - die niet speciaal behandeld wordt zoals het zou zijn in C ++; het is gewoon een constructor die hetzelfde type klasse neemt als degene die wordt geconstrueerd. Doorgaans zou een dergelijke functie de naam dup of clone hebben, maar alleen arrays hebben een ingebouwde eigenschap voor dup . Elk ander type zou een door de gebruiker gedefinieerd type moeten hebben.
toegevoegd de auteur Jonathan M Davis, de bron
@Daevius Alle opdrachten die je krijgt met lessen in D zijn het toewijzen van referenties. Het enige kopiëren dat optreedt bij het toewijzen van klassen is het kopiëren van de referentie. Dus toewijzing en constructie zijn niet gerelateerd, behalve dat je waarschijnlijk een nieuw geconstrueerd klasseobject toewijst aan een klasseverwijzing. Copy constructors zijn niet eens echt copy constructors in de C ++ betekenis. Het zijn gewoon constructeurs die toevallig hetzelfde type nemen als ze aan het bouwen zijn.
toegevoegd de auteur Jonathan M Davis, de bron

Ik zou een fout melden, en deed . De algemene regel is De D-programmeertaal , DMD-implementatie, website. Omdat ik geen TDPL bij de hand heb, ga ik hier met de implementatie over.

class A {
    int a;
    string b;
    float c;

    void opAssign(B b) {
       a = b.a;
    }
}

class B {
    int a;
}
void main()
{
    auto a = new A();
    a.a = 5;
    auto b = new B();
    b.a = 10;
    a = b;

    assert(a.a == 10);
}
0
toegevoegd
Huh. Dat is interessant.
toegevoegd de auteur Maxpm, de bron