2008-12-07 12 views
148

Dlaczego ten kod:Dziedziczenie konstruktory

class A 
{ 
    public: 
     explicit A(int x) {} 
}; 

class B: public A 
{ 
}; 

int main(void) 
{ 
    B *b = new B(5); 
    delete b; 
} 

Wynik tych błędów:

 
main.cpp: In function ‘int main()’: 
main.cpp:13: error: no matching function for call to ‘B::B(int)’ 
main.cpp:8: note: candidates are: B::B() 
main.cpp:8: note:     B::B(const B&) 

nie powinien B dziedziczą konstruktora jest?

(to jest za pomocą gcc)

Odpowiedz

248

W C++ 03 standardowe konstruktory nie mogą być dziedziczone i trzeba je dziedziczyć ręcznie, pojedynczo, wywołując implementację podstawową samodzielnie. Jeśli Twój kompilator obsługuje standard C++ 11, istnieje dziedziczenie konstruktora. Aby uzyskać więcej informacji, zobacz Wikipedia C++11 article. Z nowym standardem piszesz:

class A 
{ 
    public: 
     explicit A(int x) {} 
}; 

class B: public A 
{ 
    using A::A; 
}; 
+9

To jest zupełnie zła, bo przez ponad rok, że doszło do kompilatora, które mogą rzeczywiście zbudować powyższy kod :-) – Mikhail

+11

@Mikhail: Zarówno dzyń i g ++ powinien obsługiwać dziedziczenie konstruktorów: http: // dzyń .llvm.org/cxx_status.html http://gcc.gnu.org/projects/cxx0x.html Polecenie upvoting this as the correct answer. –

+0

po prostu pytając, czy dziedziczony konstruktor będzie mógł uzyskać dostęp do/inicjować prywatnych członków klasy podstawowej? Czy musiałbym określić je jako chronione? – Markasoftware

4

Trzeba wyraźnie zdefiniować konstruktor w B i jawnie wywołać konstruktor dla rodzica.

B(int x) : A(x) { } 

lub

B() : A(5) { } 
80

konstruktorów nie są dziedziczone. Są one wywoływane niejawnie lub jawnie przez konstruktor podrzędny.

Kompilator tworzy domyślny konstruktor (bez żadnych argumentów) i domyślny konstruktor kopii (jeden z argumentem, który jest odniesieniem do tego samego typu). Ale jeśli chcesz konstruktora, który zaakceptuje int, musisz zdefiniować go jawnie.

class A 
{ 
public: 
    explicit A(int x) {} 
}; 

class B: public A 
{ 
public: 
    explicit B(int x) : A(x) { } 
}; 

UPDATE: C++ 11, konstruktorzy mogą być dziedziczone. Zobacz szczegóły odpowiedzi Suma.

1

poprawny kod jest

class A 
{ 
    public: 
     explicit A(int x) {} 
}; 

class B: public A 
{ 
     public: 

    B(int a):A(a){ 
      } 
}; 

main() 
{ 
    B *b = new B(5); 
    delete b; 
} 

Błąd jest b/c klasa B ma nie parametr konstruktora i drugi powinien mieć klasy bazowej inicjator, aby zadzwonić do konstruktora klasy bazowej konstruktor parametr

3

jest to prosto z Bjarne Stroustrup's page:

Jeśli więc wybrać, nadal można strzelać sobie w stopę przez I nheriting konstruktorów w klasie pochodnej, w którym można zdefiniować nowe zmienne składowe wymagające inicjalizacji:

struct B1 { 
    B1(int) { } 
}; 

struct D1 : B1 { 
    using B1::B1; // implicitly declares D1(int) 
    int x; 
}; 

void test() 
{ 
    D1 d(6); // Oops: d.x is not initialized 
    D1 e;  // error: D1 has no default constructor 
} 
+0

'int x = 77;' zamiast 'int x;' rozwiąże problem –

+0

@ BЈовић: Tak, to następne zdanie na stronie Bjarne za :) –

1

Jak o użyciu funkcji szablonu powiązać wszystkie konstruktorów?

template <class... T> Derived(T... t) : Base(t...) {} 
+2

Prawdopodobnie trzeba zrobić z doskonałego korespondencji: template B (args && ... args) : A (std :: forward < Args > (args) ...) {} –

+0

Po prostu złamałeś konstruktora kopiowania Derived. – Barry

+0

Czy konstruktor Base również musi być szablonem? Kiedy zadzwonisz do Base (t ...), to Base będzie musiał zostać szablonem, bo cokolwiek jest? – Zebrafish