【FFmpeg】【bug: #20210217】C++模版多重定义问题

在我的音视频项目中使用了模版特化的RAII,

问题描述

在对音视频上下文进行封装的时候遇到了重定义问题(即模版特化导致多重定义链接错误),代码如下(AVGuard.h):

//模版特化的安全退出函数
//AVFormateContext
template <>
AVGuard<AVFormatContext>::AVGuard(){
    m_ctx = avformat_alloc_context();
}
template <>
AVGuard<AVFormatContext>::~AVGuard(){
    if (m_ctx) {
        avformat_close_input(&m_ctx);
        avformat_free_context(m_ctx);
    }
    m_ctx = nullptr;
}

//AVPacket
template <>
AVGuard<AVPacket>::AVGuard(){
    m_ctx = av_packet_alloc();
}
template <>
AVGuard<AVPacket>::~AVGuard(){
    AVPacket *m_avpacket = m_ctx;
    if (m_avpacket) {
        av_packet_free(&m_avpacket);
        m_avpacket = nullptr;
    }
}

但是如果我在AVGuard.cpp下包含这个头文件,则AVGuard.cpp、main.cpp包含多个相同函数的定义,链接时会出现重定义问题,如下:
在这里插入图片描述

产生原因分析

模版的原理为当编译器读到AVGuard时,编译器会创建一个新类。
模版定义(参数检查) --> 模版实例化(参数推导和替换)
全特化就是限定模版实现的具体类型。
当一个头文件中既有未特化的实例化类和特化的实例化类时,就出现了重复定义。

解决方法
  1. 使用内联(可以在多个文件中调用)声明特例化模版,但是一些函数的实现可能不支持内联
    不太优雅
  2. 定义普通同名函数,通过重载调用非模版函数
    太麻烦
  3. 使用static定义(文件域)
    构造函数不能声明为static
  4. 把特化从头文件中拿出,放在实现文件中
    cmd + c/v 完成,编译成功
//模版特化的安全退出函数
//AVFormateContext
template <>
AVGuard<AVFormatContext>::AVGuard(){
    av_log(NULL, AV_LOG_INFO, "AVGuard:AVFormatContext Definition Construction\n");
    m_ctx = avformat_alloc_context();
}
template <>
AVGuard<AVFormatContext>::~AVGuard(){
    if (m_ctx) {
        av_log(NULL, AV_LOG_INFO, "AVGuard:AVFormatContext Definition Deconstruction\n");
        avformat_close_input(&m_ctx);
        avformat_free_context(m_ctx);
    }
    m_ctx = nullptr;
}

打印日志:在这里插入图片描述
测试成功!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值