I have a constructor whose signature is this:
cpuInput (const std::string &label);
The actual constructor uses an initialization list referencing a superconstructor, so it looks like this:
cpuInput::cpuInput (const string &label) : StateMonitor::input(label) { }
The class compiles fine as an object file. If I compile that file together with a driver that invokes the constructor:
cpuInput *cpu = new cpuInput();
Of course I get an error from 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&)
Now here's the strange part: if I change the constructor call to:
cpuInput *cpu = new cpuInput("cpu");
And leave everything else the same, I now get:
demo.cpp:15: undefined reference to `cpuInput::cpuInput(std::string const&)'
I realize that const string&
is not quite the same as string const&
, but I had thought this was the standard way of passing a string reference (in this case, via conversion from a const char*) in C++, and this:
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;
}
Does NOT reproduce the issue, although it seems identical WRT the relevent elements to me.
So why on the one hand would g++ say:
candidates are ... cpuInput::cpuInput(const string&)
Then to new cpuInput("string")
say:
undefined reference to `cpuInput::cpuInput(std::string const&)'
For posterity, the issue was that I defined the superclass constructor (and destructor) in a header file -- the superclass is otherwise pure virtual. No doubt this is a common C++ newbie mistake.
This means that while the derived class was compiled and linked, the superclass was not. Since the derived class was compiled as an .o the compiler did not care, but using that .o in an executable that called the derived class constructor produced the linker error:
undefined reference to subclass::subclass(...)
Although what was fundamentally undefined was superclass::superclass().
As a note, it's also necessary to compile a definition of the superclass destructor if you declare it as virtual.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With