我有一个构造函数,其签名是:
cpuInput (const std::string &label);
实际的构造函数使用引用超级构造函数的初始化列表,所以它看起来像这样:
cpuInput::cpuInput (const string &label) : StateMonitor::input(label) { }
该类编译为目标文件。如果我将该文件与调用构造函数的驱动程序一起编译:
cpuInput *cpu = new cpuInput();
我当然从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&)
现在这里是奇怪的部分:如果我将构造函数调用更改为:
cpuInput *cpu = new cpuInput("cpu");
让其他一切保持不变,我现在得到:
demo.cpp:15: undefined reference to `cpuInput::cpuInput(std::string const&)'
我意识到const string&
与string const&
并不完全相同,但我认为这是传递字符串引用的标准方式(在这种情况下,通过从const char转换*)在C ++中,这个:
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;
}
不重现这个问题,虽然它似乎与我相关的WRT相同。
那么为什么一方面g ++会说:
候选人是...... cpuInput :: cpuInput(const string&amp;)
然后到new cpuInput("string")
说:
未定义引用` cpuInput :: cpuInput(std :: string const&amp;)'
答案 0 :(得分:9)
对后人来说,问题在于我在头文件中定义了超类构造函数(和析构函数) - 超类是纯虚拟的。毫无疑问,这是一个常见的C ++新手错误。
这意味着虽然编译和链接派生类,但超类却没有。由于派生类被编译为.o,编译器并不关心,但在调用派生类构造函数的可执行文件中使用.o生成了链接器错误:
undefined reference to subclass::subclass(...)
虽然从根本上未定义的是超类::超类()。
作为一个注释,如果你将它声明为虚拟的,那么编译超类析构函数的定义也是必要的。