提供的所有详细步骤 JaMIT ,但仍然被这个错误难住了。经过一番思考,我终于搞明白了。 我太粗心了 。您应该能够使用以下示例代码重现这个令人难以忍受的错误。
[jaswantp@jaswant-arch build]$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --with-isl --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-install-libiberty --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-libunwind-exceptions --disable-werror gdc_include_dir=/usr/include/dlang/gdc
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.2.0 (GCC)
// CelesetialBody.h
class CelestialBody{
public:
virtual void Print();
protected:
CelestialBody();
virtual ~CelestialBody();
};
// CelestialBody.cpp
#include "CelestialBody.h"
CelestialBody::CelestialBody() {}
CelestialBody::~CelestialBody() = default;
void CelestialBody::Print() {}
// Planet.h
#include "CelestialBody.h"
class Planet : public CelestialBody
{
public:
void Print() override;
protected:
Planet();
~Planet() override;
};
// Planet.cpp
#include "Planet.h"
Planet::Planet() {}
Planet::~Planet() {}
void Print() {} // Deliberately forgot to prefix `Planet::`
# CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
project (space_engine)
add_library (CelestialBody SHARED CelestialBody.cpp)
add_library (Planet SHARED Planet.cpp)
target_include_directories (CelestialBody PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_include_directories (Planet PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries (Planet PUBLIC CelestialBody)
# hardened linker flags to catch undefined symbols
target_link_options(Planet
PRIVATE
-Wl,--as-needed
-Wl,--no-undefined
)
我们得到了我们最喜欢的错误。
$ mkdir build
$ cd build
$ cmake ..
$ make
[ 50%] Built target CelestialBody
Scanning dependencies of target Planet
[ 75%] Building CXX object CMakeFiles/Planet.dir/Planet.cpp.o
[100%] Linking CXX shared library libPlanet.so
/usr/bin/ld: CMakeFiles/Planet.dir/Planet.cpp.o: in function `Planet::Planet()':
Planet.cpp:(.text+0x1b): undefined reference to `vtable for Planet'
/usr/bin/ld: CMakeFiles/Planet.dir/Planet.cpp.o: in function `Planet::~Planet()':
Planet.cpp:(.text+0x3d): undefined reference to `vtable for Planet'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Planet.dir/build.make:104: libPlanet.so] Error 1
make[1]: *** [CMakeFiles/Makefile2:97: CMakeFiles/Planet.dir/all] Error 2
make: *** [Makefile:103: all] Error 2
我所做的事情 Planet.cpp
当然应该用这个技巧来解决
-
查看类定义。找到第一个非纯虚函数(非 \'= 0\')且由您提供其定义的非内联虚函数(非 \'= default\')。
来自 JaMIT 的 回答。如果有其他人尝试了上述所有方法但都没有任何效果,那么也许你也像我一样,粗心地忘记 <ClassName>::
在一个或多个成员函数前面加上前缀。
我要么需要检查一下眼睛,要么需要睡一会儿。