Vraag Vermijd het kopiëren van alle constructors in subklassen


Dus een basisklasse heeft meerdere constructors:

sf::Sprite()
sf::Sprite(const Texture& texture)
sf::Sprite(const Texture& texture, const IntRect& rectangle)

En ik classiseer deze les meerdere keren:

class Sub : public sf::Sprite {
    public:
        Sub() : sf::Sprite() {};
        Sub(const Texture& texture) : sf::Sprite(texture) {};
        Sub(const Texture& texture, const IntRect& rectangle) : sf::Sprite(texture, rectangle) {};

        // My subclass specific code
};

Zoals je ziet, moet ik deze drie constructors voor elke subklasse herhalen. Is er een manier om dit te voorkomen, omdat de constructeurs meestal niets bijzonders doen? Soms ik heb nodig sommige klassespecifieke initialisatie, dus het is niet altijd haalbaar om gewoon alles te kopiëren.


20
2018-05-16 15:24


oorsprong


antwoorden:


Je kunt dit bereiken door constructeurs erven (sinds C ++ 11).

Als de gebruikverklaring een verwijzing betreft naar een constructor van een directe basis van de klasse die wordt gedefinieerd (bijv. using Base::Base;), alle constructors van die basis (negeren lidtoegang) worden zichtbaar gemaakt om de resolutie te overbelasten bij het initialiseren van de afgeleide klasse.

bijv.

class Sub : public sf::Sprite {
    public:
        using sf::Sprite::Sprite;

        // My subclass specific code
};

Als de overgenomen constructors worden gebruikt om a te initialiseren Sub, de sf::Sprite subobject wordt geïnitialiseerd met de overgenomen constructor en alle andere leden van Sub worden geïnitialiseerd als door de standaard default-constructor.

Als er een aantal speciale gevallen moeten worden verwerkt, kunt u nog steeds constructor (s) definiëren Sub, de overgenomen constructor met dezelfde handtekening zal worden verborgen.

Net als bij het gebruik van declaraties voor andere niet-statische ledenfuncties, wordt een overgeërfde constructor die overeenkomt met de handtekening van een van de constructeurs van Afgeleid, verborgen voor de zoekopdracht in de versie die is gevonden in Afgeleid.


35
2018-05-16 15:27



U kunt de using sleutelwoord om de constructor van uw basisklasse te erven, met uitzondering van de speciale klassen (standaard, kopiëren, verplaatsen). Om je standaard constructor in te korten, gebruik je gewoon = default. Als u klassespecifieke initialisatie wilt, kunt u de constructor eenvoudig opnieuw schrijven, net zoals u nu doet.

class Sub : public sf::Sprite {
    public:
        Sub() = default;
        using sf::Sprite::Sprite;

        Sub(const Texture& texture) 
        {
           // your custom code.
        };

        // My subclass specific code
};

15
2018-05-16 15:30



Als je de constructor gewoon kunt 'eryteren', gebruik dan gewoon één met exact dezelfde argumenten using zoals uitgelegd in de andere antwoorden. Echter, als uw derived class's constructor heeft aanvullende argumenten en / of vereist enige klassespecifieke initialisatie, u kunt een variadische sjabloon gebruiken.

struct base
{
  base(int);
  base(std::string const&);
  base(some_type const&);
  base(std::string const&, some_type const&);
  /* ... */
};

struct derived : base
{
  template<typename...Args>
  derived(some_other_type const&x, Args&&...args)
  : base(std::forward<Args>(args)...)
  , private_datum(x)
  {
    construction_details();          // class-specific initialisation
  }
private:
  some_other_type private_datum;
  void construction_details();       // implemented in source code
};

7
2018-05-16 15:49