代码之家  ›  专栏  ›  技术社区  ›  Ashutosh

在c++中获取丢失的vtable错误,导致“clang:error:linker命令失败,退出代码为1”

  •  -1
  • Ashutosh  · 技术社区  · 1 年前

    我正在努力学习c++中的接口和类。在运行代码时,我得到了一个丢失的vtable错误。我的完整代码是:

    #include <iostream>
    
    class IGPS{
    public:
        virtual float getLatitude();
    };
    
    class MockGPS: public IGPS{
    public:
        virtual float getLatitude() override;
    };
    
    float MockGPS::getLatitude(){
        return  11.3f;
    }
    
    void DriveRobot(IGPS& gps){
        float lat = gps.getLatitude();
        std::cout << "Lat : " << lat;
    }
    
    int main(int argc, const char * argv[]) {
        MockGPS gps;
        DriveRobot(gps);
        std::cout<< " Hello World! " << std::endl;
        
        return 0;
    }
    
    

    我得到的错误跟踪是

    base ❯ clang main.cpp -std=c++11
    Undefined symbols for architecture arm64:
      "std::__1::locale::use_facet(std::__1::locale::id&) const", referenced from:
          std::__1::ctype<char> const& std::__1::use_facet[abi:ue170006]<std::__1::ctype<char>>(std::__1::locale const&) in main-4b1700.o
      "std::__1::ios_base::getloc() const", referenced from:
          std::__1::basic_ios<char, std::__1::char_traits<char>>::widen[abi:ue170006](char) const in main-4b1700.o
      "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::__init(unsigned long, char)", referenced from:
          std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::basic_string[abi:ue170006](unsigned long, char) in main-4b1700.o
      "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::~basic_string()", referenced from:
          std::__1::ostreambuf_iterator<char, std::__1::char_traits<char>> std::__1::__pad_and_output[abi:ue170006]<char, std::__1::char_traits<char>>(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char>>, char const*, char const*, char const*, std::__1::ios_base&, char) in main-4b1700.o
          std::__1::ostreambuf_iterator<char, std::__1::char_traits<char>> std::__1::__pad_and_output[abi:ue170006]<char, std::__1::char_traits<char>>(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char>>, char const*, char const*, char const*, std::__1::ios_base&, char) in main-4b1700.o
      "std::__1::basic_ostream<char, std::__1::char_traits<char>>::put(char)", referenced from:
          std::__1::basic_ostream<char, std::__1::char_traits<char>>& std::__1::endl[abi:ue170006]<char, std::__1::char_traits<char>>(std::__1::basic_ostream<char, std::__1::char_traits<char>>&) in main-4b1700.o
      "std::__1::basic_ostream<char, std::__1::char_traits<char>>::flush()", referenced from:
          std::__1::basic_ostream<char, std::__1::char_traits<char>>& std::__1::endl[abi:ue170006]<char, std::__1::char_traits<char>>(std::__1::basic_ostream<char, std::__1::char_traits<char>>&) in main-4b1700.o
      "std::__1::basic_ostream<char, std::__1::char_traits<char>>::sentry::sentry(std::__1::basic_ostream<char, std::__1::char_traits<char>>&)", referenced from:
          std::__1::basic_ostream<char, std::__1::char_traits<char>>& std::__1::__put_character_sequence[abi:ue170006]<char, std::__1::char_traits<char>>(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, char const*, unsigned long) in main-4b1700.o
      "std::__1::basic_ostream<char, std::__1::char_traits<char>>::sentry::~sentry()", referenced from:
          std::__1::basic_ostream<char, std::__1::char_traits<char>>& std::__1::__put_character_sequence[abi:ue170006]<char, std::__1::char_traits<char>>(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, char const*, unsigned long) in main-4b1700.o
          std::__1::basic_ostream<char, std::__1::char_traits<char>>& std::__1::__put_character_sequence[abi:ue170006]<char, std::__1::char_traits<char>>(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, char const*, unsigned long) in main-4b1700.o
      "std::__1::basic_ostream<char, std::__1::char_traits<char>>::operator<<(float)", referenced from:
          DriveRobot(IGPS&) in main-4b1700.o
      "std::__1::cout", referenced from:
          DriveRobot(IGPS&) in main-4b1700.o
          _main in main-4b1700.o
      "std::__1::ctype<char>::id", referenced from:
          std::__1::ctype<char> const& std::__1::use_facet[abi:ue170006]<std::__1::ctype<char>>(std::__1::locale const&) in main-4b1700.o
      "std::__1::locale::~locale()", referenced from:
          std::__1::basic_ios<char, std::__1::char_traits<char>>::widen[abi:ue170006](char) const in main-4b1700.o
          std::__1::basic_ios<char, std::__1::char_traits<char>>::widen[abi:ue170006](char) const in main-4b1700.o
      "std::__1::ios_base::__set_badbit_and_consider_rethrow()", referenced from:
          std::__1::basic_ostream<char, std::__1::char_traits<char>>& std::__1::__put_character_sequence[abi:ue170006]<char, std::__1::char_traits<char>>(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, char const*, unsigned long) in main-4b1700.o
      "std::__1::ios_base::clear(unsigned int)", referenced from:
          std::__1::ios_base::setstate[abi:ue170006](unsigned int) in main-4b1700.o
      "std::terminate()", referenced from:
          ___clang_call_terminate in main-4b1700.o
      "typeinfo for IGPS", referenced from:
          typeinfo for MockGPS in main-4b1700.o
      "vtable for IGPS", referenced from:
          IGPS::IGPS() in main-4b1700.o
       NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
      "vtable for __cxxabiv1::__si_class_type_info", referenced from:
          typeinfo for MockGPS in main-4b1700.o
       NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
      "___cxa_begin_catch", referenced from:
          std::__1::basic_ostream<char, std::__1::char_traits<char>>& std::__1::__put_character_sequence[abi:ue170006]<char, std::__1::char_traits<char>>(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, char const*, unsigned long) in main-4b1700.o
          ___clang_call_terminate in main-4b1700.o
      "___cxa_end_catch", referenced from:
          std::__1::basic_ostream<char, std::__1::char_traits<char>>& std::__1::__put_character_sequence[abi:ue170006]<char, std::__1::char_traits<char>>(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, char const*, unsigned long) in main-4b1700.o
          std::__1::basic_ostream<char, std::__1::char_traits<char>>& std::__1::__put_character_sequence[abi:ue170006]<char, std::__1::char_traits<char>>(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, char const*, unsigned long) in main-4b1700.o
      "___gxx_personality_v0", referenced from:
          /private/var/folders/x9/hk8k3w4s6yl4hp1jbgk4qc680000gn/T/main-4b1700.o
    ld: symbol(s) not found for architecture arm64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    
    

    我能理解的主要错误是:

    NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
    

    关于如何解决此错误的任何建议。 当做

    我正在努力学习c++中的接口和类。 我试着在函数定义中添加大括号,比如

    virtual float getLatitude() {};
    

    virtual float getLatitude(){} override;
    
    

    正如一些网站所建议的那样,但它给出了“非void函数不返回值”的语法错误。 我使用Xcode v15.3进行编程。我的clang版本是15.0.0

    1 回复  |  直到 1 年前
        1
  •  3
  •   Some programmer dude    1 年前

    你实际上有 问题。

    第一个是你使用 clang 建造。此程序用于构建 C 程序。用于C++ clang++ 。大多数错误实际上都来自于此。

    第二个问题是标题中提到的问题,当您有一个未定义(实现)的非抽象虚拟函数时,这是典型的问题。

    在你的情况下,它是 IGPS::getLatitude 作用要么定义它:

    virtual float getLatitude() { return 0.0f; }
    

    或者将其标记为抽象:

    virtual float getLatitude() = 0;
    

    另一方面,除非您有非常具体的要求,否则不要使用 float 使用 double .

    一旦您将一个函数声明为虚拟的,它在所有子类中也将是虚拟的。你不必重复 virtual 关键字。