【问题标题】:"Undefined reference" to constructor which is defined对已定义的构造函数的“未定义引用”
【发布时间】:2013-08-11 14:32:11
【问题描述】:

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

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;
}             

重现该问题,尽管它似乎与我的相关元素相同。

那么为什么一方面g++会说:

候选人是... cpuInput::cpuInput(const string&)

然后对new cpuInput("string")说:

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

【问题讨论】:

  • 听起来您没有链接到定义cpuInput::cpuInput(std::string const &amp;) 的目标文件。
  • @VaughnCato :从技术上讲,链接是指向包含.o.a 文件,但是,也许我为C++ 库错误地调用了ar?将调查...
  • 关于错误信息中的参数格式不同,这是因为一个是编译器生成的,另一个是链接器生成的,它们使用的代码并不完全相同。
  • 好的,这是因为我在 .hpp 文件中定义了(纯虚拟)超类的构造函数,这意味着它从未正确编译过。呵呵。

标签: c++ g++


【解决方案1】:

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

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

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

虽然根本上未定义的是 superclass::superclass()。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    相关资源
    最近更新 更多