You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

继承纯虚基类属性需重定义吗?附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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 03:22:22