11 grudnia 2013

[C++11] Dziedziczenie/unhide konstruktora

W nowym standardzie klasa pochodna może odziedziczyć (jest to właściwie mechanizm unhide, jaki był do tej pory dostępny tylko dla metod) swój konstruktor z jednej lub więcej klas bazowych. Jeżeli taki sam konstruktor (z takimi samymi parametrami) pojawi się w kilku klasach bazowych należy zdefiniować własną wersję w klasie pochodnej. Ciekaw linki:
Mechanizm pozwala na niejawne zadeklarowanie wszystkich konstruktorów, które nie są: domyślnymi, copy/move ani konstruktorami o takiej samej sygnaturze jak już istniejące konstruktory z klasy bazowej.

W poniższym przykładzie klasa Derived, dziedziczy z dwóch klas bazowych, dla których zachodzi konflikt dla Base1(int) i Base2(int), powodujący błąd kompilacji. Aby się go pozbyć w klasie pochodnej należało stworzyć własną wersję tego konstruktora. Ponieważ w Derived pojawił się już konstruktor, kompilator nie wygeneruje za nas konstruktora domyślnego (linia 32 - nie działa) - można stworzyć własną wersję.
#include <iostream>
#include <vector>
using namespace std;

struct Base1 {
    Base1() { cout << "Base1" << endl; }
    Base1(std::vector<int>) { cout << "Base1(vector)" << endl; }
    Base1(int) { cout << "Base1(int)" << endl; }
};

struct Base2 {
    Base2() { cout << "Base2" << endl; }
    Base2(int) { cout << "Base2(int)" << endl; }
};

struct Derived : public Base1, public Base2 {
    using Base1::Base1;
    using Base2::Base2;

    // Ta wersja konstruktora znajduje się w Base1 i Base2
    // należy zdefiniować jej własną wersję!
    Derived(int i) : Base1(i), Base2(i) {
        cout << "Derived(int)" << endl;
    }
};

struct SimpleDerived : public Base1 {
   using Base1::Base1;
};

int main() {
//  Derived d1;
    Derived d2(789);
    Derived d3({1, 2});

    SimpleDerived s1;
    SimpleDerived s2(42);
    SimpleDerived s3({1, 2});

    return 0;
}
Wynik:
Base1(int)
Base2(int)
Derived(int)

Base1(vector)

Base2
Base1

Base1(int)

Base1(vector)

Brak komentarzy:

Prześlij komentarz