链接时未定义 C++ 虚函数 - 为什么?

标签 c++ inheritance undefined virtual-functions

我在使用 C++ 中的虚函数时遇到了一些麻烦,我可能在构造函数中误用了它们。问题是,当将一个组件库(由我编写)链接到我的最终可执行文件时,一个虚函数被标记为未定义,即使我已经为它编写了一个实现并链接了它。

我有以下类(class):

template<class BufferType, class ConnectionType, class HandlerType>
class UdpConnection
{
public:
UdpConnection(size_t dispatchCount) : service(),
        listener(service),
        pool(dispatchCount), sysMsgHandlers(),
        bufferPool(), buffers()
    {
        assert(dispatchCount > 0);
        initBuffers(dispatchCount);
        initSysHandlers();
    }
protected:
    virtual void initSysHandlers() = 0;
}

在我的子类中:

class UdpClient : public UdpConnection<SyncBufferHandler, UdpClient, ClientNetworkHandler>
{
    protected:
        void initSysHandlers();
}

和子类源文件:

void UdpClient::initSysHandlers()
{

}

如您所见,我在构造函数中调用了一个虚函数。据我所知,这应该没问题,因为我知道我的子类构造函数不会被调用,所以我不能使用任何实例变量,但我只是将一些子类特定的项目添加到标准::映射。

Linking CXX static library libnetwork.a
[ 75%] Built target network                                                                                           
Scanning dependencies of target testclient
[ 87%] Building CXX object CMakeFiles/testclient.dir/src/test/testclient.cpp.o                                        
Linking CXX executable testclient                                                                                     
src/network/libnetwork.a(udpclient.cpp.o): In function `voip::network::UdpConnection<voip::network::client::SyncBufferHandler, voip::network::client::UdpClient, voip::network::client::ClientNetworkHandler>::UdpConnection(unsigned long)':
udpclient.cpp:(.text._ZN4voip7network13UdpConnectionINS0_6client17SyncBufferHandlerENS2_9UdpClientENS2_20ClientNetworkHandlerEEC2Em[voip::network::UdpConnection<voip::network::client::SyncBufferHandler, voip::network::client::UdpClient, voip::network::client::ClientNetworkHandler>::UdpConnection(unsigned long)]+0x10d): undefined reference to `voip::network::UdpConnection<voip::network::client::SyncBufferHandler, voip::network::client::UdpClient, voip::network::client::ClientNetworkHandler>::initSysHandlers()'
collect2: ld returned 1 exit status

我在这里做错了什么?请询问您是否需要更多信息,希望信息尽可能简短!

最佳答案

您正在从基类构造函数中调用虚函数。构造和销毁期间虚函数的调度有特殊规则:

实际上,基类UdpConnection的构造函数在执行时,对象的动态类型是UdpConnection,而不是UdpClient,所以所选虚函数的最终覆盖是 UdpConnection 的覆盖,而不是最派生类 UdpClient

这意味着当您在 UdpConnection 构造函数中调用 initSysHandlers() 时,调用的是 UdpConnection::initSysHandlers(),永远,而不是最派生类中的重写。因为您没有提供 UdpConnection::initSysHandlers() 的定义,所以您会收到链接器错误。

专家的建议是你应该"Never Call Virtual Functions during Construction or Destruction" .

关于链接时未定义 C++ 虚函数 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4980406/

相关文章:

c++ - 如何获取 std::filesystem::path 中的最后一个目录?

c++ - Visual Studio : How to specify different runtime libraries for the linker?(/MTd、MDd 等)

Codeigniter 多级继承

php - 未定义索引 : topic in C:includes\topic_list. php 第 9 行

angular - 接口(interface)对象属性未定义,但有 Angular 值

c++ - 编译先前预处理的文件更改输出

c++ - ebp + 6 而不是 JIT 编译器中的 +8

c++ - Qt 信号和槽 : permissions

php - 管理一个应用的多个专业版本的最佳实践

javascript - Sequelize 模型自定义方法返回未定义