继承纯虚基类属性需重定义吗?附vtable未定义错误咨询
C++纯虚基类继承问题:链接错误
undefined reference to vtable for Son 问题描述
从纯虚基类Father继承m_name和m_properties属性,子类Son拥有自身属性m_school,希望在main函数中初始化这三个属性。已知m_school的初始化方式,但不确定父类属性的实现是否正确(曾在Son中重复定义父类属性,注释后仍报错),当前编译出现链接错误undefined reference to vtable for Son,请求解决。
错误信息
"C:\Program Files\JetBrains\CLion 2023.1\bin\cmake\win\x64\bin\cmake.exe" --build C:\Users\mirek\CLionProjects\family\cmake-build-debug --target family -j 6 [1/3] Building CXX object CMakeFiles/family.dir/main.cpp.obj [2/3] Building CXX object CMakeFiles/family.dir/Son.cpp.obj [3/3] Linking CXX executable family.exe FAILED: family.exe cmd.exe /C "cd . && C:\PROGRA~1\JETBRA~1\CLION2~1.1\bin\mingw\bin\G__~1.EXE -g CMakeFiles/family.dir/main.cpp.obj CMakeFiles/family.dir/Father.cpp.obj CMakeFiles/family.dir/Son.cpp.obj -o family.exe -Wl,--out-implib,libfamily.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ." C:\Program Files\JetBrains\CLion 2023.1\bin\mingw\bin/ld.exe: CMakeFiles/family.dir/Son.cpp.obj:Son.cpp:(.rdata$.refptr._ZTV3Son[.refptr._ZTV3Son]+0x0): undefined reference to `vtable for Son' collect2.exe: error: ld returned 1 exit status ninja: build stopped: subcommand failed.
相关代码
Father.h
#include <iostream> #include <string> #include <vector> #include "Father.h" // 存在循环引用错误 class Father { protected: std::string m_name; std::vector<std::string> m_properties; public: virtual int calculateSalary() = 0; };
Father.cpp
#include "Father.h"
Son.h
#include <iostream> #include "Father.h" class Son: public Father{ std::string m_school; //std::string m_name; //is it right? //std::vector<std::string> m_properties; //is it right? public: Son(std::string school, std::string name, std::vector<std::string> properties); int calculateSalary(); };
Son.cpp
#include "Son.h" Son::Son(std::string school, std::string name, std::vector<std::string> properties){ m_school = school; m_name = name; m_properties = properties; }
main.cpp
int main() { Son* son1 = new Son("Harward", "Mirek", {"asd","yxc"}); //Son's school attribute and Father's attribute name and properties vector }
解决方案
- 补全子类纯虚函数的实现:链接错误核心原因是
Son声明了重写纯虚函数calculateSalary()但未提供实现,导致编译器无法生成虚函数表。在Son.cpp中添加:int Son::calculateSalary() { // 编写具体业务逻辑,示例返回固定值 return 5000; } - 删除父类头文件的循环引用:
Father.h中#include "Father.h"属于无效循环引用,直接删除该行即可。 - 父类属性的正确处理:不要在子类
Son中重复定义m_name和m_properties,子类通过继承已拥有这些protected属性,重复定义会隐藏父类成员,保持当前注释状态即可。 - 优化构造函数初始化方式(可选):使用初始化列表替代构造函数内赋值,提升容器、字符串等类型的初始化效率:
Son::Son(std::string school, std::string name, std::vector<std::string> properties) : m_school(std::move(school)), m_name(std::move(name)), m_properties(std::move(properties)) {}
补充说明
纯虚基类要求所有非抽象子类必须实现所有纯虚函数,否则子类会被视为抽象类无法实例化。同时,虚函数表的生成依赖于所有虚函数的实现,缺失实现会导致链接阶段报错。
内容的提问来源于stack exchange,提问作者Mirek
相关产品推荐
相关产品推荐

