c++ - 子类不会调用从模板基类继承的函数
问题描述
下面是我的代码。我删除了与问题无关的内容以保持简洁:
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;
}
我的主要问题如下:
- 此代码编译没有问题(甚至没有警告)。
- 我的期望是
device->test()
( 1)将执行HM62256 从 IMemory继承的test()
方法。因此它应该将IMemory:test()打印到控制台。它不是。我在所述方法上设置了断点,但调试器没有命中它们。相反,执行只是简单地进行,没有任何内容打印到控制台。我设置了一个断点,它确实击中了它。test()
delete device;
我的第二个问题是,由于代码编译得很好, (1)处的函数调用必须调用一些东西,对吧?它叫什么?
附加信息:
- 编译器: GCCC 8.3.0 针对 arm-linux 和 C++20
- 使用CMake
解决方案
因此,正如@Quimby 在评论中所建议的那样,我的问题在我的代码中的其他地方。
我是如何发现这个问题的:
- 为编译器和链接器启用了一些清理标志。这让编译器抱怨我做错了一些事情,其中一些可能是我问题的根源
add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address -static-libasan)
我的问题是什么:
坦率地说,我不知道。最有可能的是,某些东西正在破坏 vtable。不过我有几个嫌疑人:
- 我
const
在 的成员函数中增加了一个变量IMemory
,编译器在添加清理标志之前没有抱怨。 - 我正在使用 C++20 的格式化库。再次,编译器在添加清理标志之前没有抱怨,但在抱怨它找不到该包含之后。这让我相信要么工具链本身坏了,要么我安装的工具链坏了。
IMemory
我在声明和定义中都有几个带有默认参数的函数。添加清理标志后,编译器抱怨了这一点。解决方法是将参数的默认值仅放在声明中。
修复这三个后,编译器愉快地编译了代码,并且出现了预期的结果。请注意,我必须静态链接libasan
才能使清理标志起作用。
推荐阅读
- excel - 将字符串从 Excel 单元格粘贴到 Outlook 邮件时保留回车符
- linux - Objdump 中的 -s(或 --full-contents)标志有什么作用?
- angular - 如何在页面重新加载时关闭垫子扩展面板
- dataweave - 将 json 映射到平面文件的 dataweave 表达式
- vb.net - 无法为 VB 导入 Quartz.NET 库
- php - 如何显示来自 Codeigniter 和 mongodb 的所有索引数据?
- svn - 在 svn 中设置存储库权限
- php - 使用 API 在 akeneo api 中添加产品的问题
- php - 无法使用 simplexml_load_string 解析 XML
- c# - 从多个线程更新 GUI