I am trying to study interfaces and classes in c++. While running a code, I am getting a missing vtable error. My complete code is:
#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;
}
The error trace that I am getting is
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)
Main error that I can understand is :
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
Any suggestions as to how to get this error solved. Regards
I am trying to learn the interfaces and classes in c++. I tried adding braces to the function definitions like
virtual float getLatitude() {};
or
virtual float getLatitude(){} override;
as suggested in some websites, but it gives "Non void function does not return a value" syntax error. I am using Xcode v15.3 for programming. My clang version is 15.0.0
You actually have two problems.
The first is that you use clang
to build. This program is to build C programs. For C++ use clang++
. Most of the errors are actually from this.
The second problem, the one mentioned in the title, is typical when you have a non-abstract virtual function that you don't define (implement).
In your case it's the IGPS::getLatitude
function. Either define it:
virtual float getLatitude() { return 0.0f; }
Or mark it as abstract:
virtual float getLatitude() = 0;
On a totally different note, unless you have very specific requirements, don't use float
. Use double
.
And once you have declared a function to be virtual, it will be virtual in all child-classes as well. You don't have to repeat the virtual
keyword.