2013-08-11 13 views
5

Mam konstruktora, którego podpis brzmi:„Niezdefiniowany odniesienia” do konstruktora, który jest zdefiniowany

cpuInput (const std::string &label); 

Rzeczywisty konstruktor używa listy inicjalizacji odwoływania się superkonstruktor, więc wygląda to tak:

cpuInput::cpuInput (const string &label) : StateMonitor::input(label) { } 

Klasa kompiluje dobrze jako plik obiektowy. Jeśli mogę skompilować ten plik razem z kierowcą, który wywołuje konstruktor:

cpuInput *cpu = new cpuInput(); 

Oczywiście pojawia się błąd z g++:

demo.cpp:15:31: error: no matching function for call to ‘cpuInput::cpuInput()’ 
demo.cpp:15:31: note: candidates are: 
In file included from demo.cpp:3:0: 
input_cpusage/cpuInput.hpp:7:3: note: cpuInput::cpuInput(const string&) 

Teraz tutaj jest dziwny część: jeśli zmienię wywołanie konstruktora :

cpuInput *cpu = new cpuInput("cpu"); 

I zostawić wszystko inne samo, teraz uzyskać:

demo.cpp:15: undefined reference to `cpuInput::cpuInput(std::string const&)' 

Zdaję sobie sprawę, że const string& to nie to samo, co , ale myślałem, że był to standardowy sposób przekazywania odwołania do ciągu znaków (w tym przypadku przez konwersję z const char *) w C++, i to:

class A { 
    public: 
     A (const string &s) : x(s) { cout << x << endl; } 
    private: 
     const string x; 
}; 

class B : A { 
    public: 
     B (const string &s) : A(s) { } 
}; 

int main (void) { 
    new B("test"); 
    return 0; 
}    

nie odtworzyć problem, chociaż wydaje się identyczny WRT elementy dowiemy się z mnie.

Więc dlaczego z jednej strony byłby g ++ powiedzieć:

candidates are ... cpuInput::cpuInput(const string&)

Następnie do new cpuInput("string") powiedzieć:

undefined reference to `cpuInput::cpuInput(std::string const&)'

+3

Wygląda na to, że nie łączysz się z plikiem obiektu, w którym zdefiniowano 'cpuInput :: cpuInput (std :: string const &)'. –

+0

@VaughnCato: Technicznie jest to link do pliku '.a', który zawiera' .o', jednak może wywołuję 'ar' niepoprawnie dla biblioteki C++? Zbada ... – delicateLatticeworkFever

+1

Co do różnych formatów parametrów w komunikatach o błędach, to dlatego, że jeden jest generowany przez kompilator, a drugi przez linker, nie używają tego samego kodu. – hvd

Odpowiedz

8

dla potomności, problem był taki, że zdefiniowany konstruktor nadklasy (i destruktora) w plik nagłówkowy - nadklasa jest inaczej czysta wirtualna. Bez wątpienia jest to powszechny błąd dla początkujących w C++.

Oznacza to, że podczas gdy klasa pochodna została skompilowana i powiązana, nadklasa nie była. Ponieważ klasa pochodna został skompilowany jako .o kompilator nie obchodzi, ale przy użyciu tego .o w pliku wykonywalnego, który wywołał pochodzący konstruktora klasy produkowane łącznikową błąd:

undefined reference to subclass::subclass(...) 

Chociaż co było zasadniczo niezdefiniowane superklasa :: nadklasa().

Na marginesie, konieczne jest również skompilowanie definicji destruktora klasy nadrzędnej, jeśli zostanie zadeklarowana jako wirtualna.

Powiązane problemy