首页 > 解决方案 > 子类不会调用从模板基类继承的函数

问题描述

下面是我的代码。我删除了与问题无关的内容以保持简洁:

IChip.hpp(根抽象类)

class IChip {
    public:
    virtual bool test() noexcept = 0;
};

IMemory.hpp(包含所有内存共有的一些功能的摘要,读/写用于说明)

#include "IChip.hpp"

template <typename TAddr, typename TWord>
class IMemory: public IChip {
    protected:
    ...

    public:
    virtual TWord read(const TAddr addr) const noexcept = 0;
    virtual void write(const TAddr addr, const TWord data) const noexcept = 0;
    ...
    bool test() noexcept final override;
};

IMemory.cpp

#include "IMemory.hpp"

template <typename TAddr, typename TWord>
bool IMemory<TAddr, TWord>::test() noexcept {
    std::cout << "IMemory:test()" << std::endl;
    ...
    return true;
}

// Explicit instantiation. (Actually resides in a separate file IMemory.impl.cpp, but included here for clarity)
template class IMemory<uint16_t, uint8_t>;

HM62256.hpp(为了说明再次读/写)

#include "IMemory.hpp"

class HM62256: public IMemory<uint16_t, uint8_t> {
    private:
    ...

    public:
    ...
    uint8_t read(uint16_t addr) const noexcept final override;
    void write(uint16_t addr, uint8_t data) const noexcept final override;
    ...
};

HM62256.cpp

#include "HM62256.hpp"

uint8_t HM62256::read(uint16_t addr) const noexcept {
    uint8_t result = 0;
    ...
    return result;
}

void HM62256::write(uint16_t addr, uint8_t data) const noexcept {
    ...
}

主文件

int main(int argc, char *argv[]) {
    const uint8_t ADDR_PINS[] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
    const uint8_t DATA_PINS[] = {19, 20, 21, 22, 23, 24, 25, 26};
    HM62256 *device = new HM62256(ADDR_PINS, DATA_PINS, 2, 3, 27);

    device->test();    // (1)

    delete device;
}

我的主要问题如下:

我的第二个问题是,由于代码编译得很好, (1)处的函数调用必须调用一些东西,对吧?它叫什么

附加信息:

标签: c++templatesinheritance

解决方案


因此,正如@Quimby 在评论中所建议的那样,我的问题在我的代码中的其他地方。

我是如何发现这个问题的:

  • 为编译器和链接器启用了一些清理标志。这让编译器抱怨我做错了一些事情,其中​​一些可能是我问题的根源
add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address -static-libasan)

我的问题是什么:

坦率地说,我不知道。最有可能的是,某些东西正在破坏 vtable。不过我有几个嫌疑人:

  • const在 的成员函数中增加了一个变量IMemory,编译器在添加清理标志之前没有抱怨。
  • 我正在使用 C++20 的格式化库。再次,编译器在添加清理标志之前没有抱怨,但在抱怨它找不到该包含之后。这让我相信要么工具链本身坏了,要么我安装的工具链坏了。
  • IMemory我在声明和定义中都有几个带有默认参数的函数。添加清理标志后,编译器抱怨了这一点。解决方法是将参数的默认值仅放在声明中。

修复这三个后,编译器愉快地编译了代码,并且出现了预期的结果。请注意,我必须静态链接libasan才能使清理标志起作用。


推荐阅读