Moninkertainen perintö C ++: ssa ja timanttiongelma

Toisin kuin monet muut olio-ohjelmointikielet, C ++ sallii useiden perintöjen.

Useiden perintöjen avulla lapsiluokka voi periä useammasta kuin yhdestä vanhempaluokasta.

Aluksi se näyttää olevan erittäin hyödyllinen ominaisuus. Mutta käyttäjän on pidettävä mielessä muutama gotcha toteuttaessaan tätä ominaisuutta.

Seuraavissa esimerkeissä käsitellään muutamia skenaarioita, joista on oltava tietoinen.

Aloitamme yksinkertaisella esimerkillä tämän käsitteen selittämiseksi C ++: ssa.

Tämän koodin lähtö on seuraava:

I'm breathing as a snake.I’m crawling as a snake.

Yllä olevassa esimerkissä meillä on perusluokka nimeltä LivingThing . eläintenja matelijaluokat perivät siitä. Vain eläinluokka ohittaa menetelmän breathe(). Snake luokka perii päässä eläinten ja Reptile luokissa. Se ohittaa heidän menetelmänsä. Yllä olevassa esimerkissä ei ole ongelmaa. Koodimme toimii hyvin.

Nyt lisätään hieman monimutkaisuutta.

Entä jos matelijaluokka ohittaa breathe()menetelmän?

Snake luokka ei tiedä mikä breathe()tapa soittaa. Tämä on ”timanttiongelma”.

Timanttiongelma

Katso alla olevaa koodia. Se on kuin yllä olevan esimerkin koodi, paitsi että olemme ohittaneet Reptile- luokan breathe()menetelmän .

Jos yrität koota ohjelmaa, se ei onnistu. Tuijotat alla olevan kaltaista virheilmoitusta.

member ‘breathe’ found in multiple base classes of different types

Virhe johtuu useiden perintöjen ”timanttiongelmasta”. Snake luokka ei tiedä mikä breathe()tapa soittaa.

Ensimmäisessä esimerkissä vain eläinluokka oli ohittanutbreathe()menetelmä. Reptile luokka ei ollut. Siksi Snake- luokan ei ollut kovin vaikeaa selvittää, mihin breathe()tapaan soittaa. Ja Snake- luokka päätyi kutsumaan Animal- luokan breathe()menetelmää .

Toisessa esimerkissä Snake-luokka perii kaksibreathe() menetelmää. breathe()Menetelmä eläinten ja Reptile luokassa. Koska emme ole ohittaneet breathe()menetelmää Snake- luokassa, on epäselvyyttä.

C ++: lla on monia tehokkaita ominaisuuksia, kuten moniperintö. Mutta ei ole välttämätöntä, että käytämme kaikkia sen tarjoamia ominaisuuksia.

En halua käyttää useita perintöjä ja käyttää virtuaalista perintöä sen sijaan.

Virtuaalinen perintö ratkaisee klassisen "timanttiongelman". Se varmistaa, että lapsiluokka saa vain yhden esiintymän yhteisestä perusluokasta.

Toisin sanoen Käärme- luokassa on vain yksi LivingThing- luokan esiintymä . Eläinten ja Reptile luokat jakaa tässä tapauksessa.

Tämä ratkaisee aiemmin saamamme kääntöaikavirheen. Abstraktien luokkien johdettujen luokkien on korvattava perusluokassa määritellyt puhtaat virtuaalifunktiot.

Toivon, että nautitte tästä yleiskatsauksesta moniperintöön ja "timanttiongelmaan".