7

我有一个构造函数,其签名是这样的:

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&,但我认为这是在 C++ 中传递字符串引用(在本例中,通过从 const char* 转换)的标准方式,并且:

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&)

然后new cpuInput("string")说:

对` cpuInput::cpuInput(std::string const&) '的未定义引用

4

1 回答 1

11

对于后代,问题是我在头文件中定义了超类构造函数(和析构函数)——超类是纯虚拟的。毫无疑问,这是一个常见的 C++ 新手错误。

这意味着当派生类被编译和链接时,超类没有。由于派生类被编译为 .o 编译器并不关心,但是在调用派生类构造函数的可执行文件中使用该 .o 会产生链接器错误:

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

尽管根本上未定义的是 superclass::superclass()。

请注意,如果将超类析构函数声明为虚拟,则还需要编译超类析构函数的定义。

于 2013-08-11T15:49:49.310 回答