2016-09-26 13 views
8

wpadłem na bardzo bolesnego błędu dzisiaj, tutaj jest MWE:Dziedziczenie drugiego poziomu konstruktor klasy bazowej: cicha błąd

#include <iostream> 

class X { 

public: 
    X() { std::cout << "Default" << std::endl; } 
    X(int a) { std::cout << a << std::endl; } 
}; 

class Y : public X { }; 

class Z : public Y { 
    using X::X; 
}; 

int main() { 
    Z instance{3}; 
} 

Wbrew moim oczekiwaniom „Default” zostanie wydrukowany. Oczywiście kod jest wadliwy, ponieważ odziedziczeni konstruktorzy z Z próbują zainicjować X bez określania sposobu konstruowania Y(∗). Ale czy kompilator nie powinien narzekać? Jakie jest uzasadnienie domyślnego konstruktora Y (a następnie X) wywoływania, całkowicie cicho ignorując mój parametr 3? Czy jest to udokumentowane gdzieś w standardzie? Czy jest to błąd w moim kompilatorze?

Moje środowisko to gcc version 6.2.1 20160916 (Red Hat 6.2.1-2). Ostrzeżenie o kompilatorze nie jest produkowane nawet z -Weffc++ -Wall -Wextra -pedantic.

+1

Pytanie, które łączysz, dotyczy języka C#, a nie C++. –

+0

Myślę, że logika konstrukcji pozostaje taka sama, "Y" nie może pozostać niezdefiniowana i konstruuje 'X' na swojej drodze. Ale nie powinien akceptować parametru, którego własny konstruktor nie ma. –

Odpowiedz

2

Jest to błąd g ++, kod jest nieprawidłowy. Tylko konstruktorzy z baz bezpośrednich mogą być dziedziczone:

[namespace.udecl] §3 Jeżeli taka użyciu deklaracja nazwiska konstruktora The nested-name-specifier wyznacza bezpośredni klasy bazowej klasy, która jest zdefiniowana:

+0

Dzięki za cytat! Zobaczę, czy mogę to zgłosić, czy też ktoś już to zrobił. –

Powiązane problemy