I have a program in xcode and had the thing running fine with just the skeleton. I went to add some code in and when I added three functions, all private, two of which are inline to both the .h and .cpp. When I went to compile I got linker errors for god knows what reason. The class I am making functions in also inherits from a struct but i dont think that should be a problem. Ill post the code below. (there's a lot to this project so i cant post everything)
#ifndef HEAP_SORT_H
#define HEAP_SORT_H
#include "Interfaces02.h"
#include "CountedInteger.h"
class HeapSort : public IHeapSort {
public:
HeapSort();
virtual ~HeapSort();
virtual void buildHeap(std::vector<CountedInteger>& vector);
virtual void sortHeap(std::vector<CountedInteger>& vector);
private:
virtual unsigned int l(int i);
virtual unsigned int r(int i);
virtual void fixDown(std::vector<CountedInteger>& vector, int p);
};
#endif
#include "HeapSort.h"
#include "CountedInteger.h"
HeapSort::HeapSort()
{
}
HeapSort::~HeapSort()
{
}
void HeapSort::buildHeap(std::vector<CountedInteger>& vector)
{
int i = ((int) vector.size()) - 1;
for(; i > 1; i--)
{
fixDown(vector, i);
}
}
void HeapSort::sortHeap(std::vector<CountedInteger>& vector)
{
}
inline unsigned int l(int i)
{
return ((i*2)+1);
}
inline unsigned int r(int i)
{
return ((i*2)+2);
}
void fixDown(std::vector<CountedInteger>& vector, int p)
{
int largest;
if(l(p) <= vector.size() && vector[l(p)] > vector[p])
{
largest = l(p);
}
else
{
largest = p;
}
if(r(p) <= vector.size() && vector[r(p)] > vector[p])
{
largest = r(p);
}
if(largest != p)
{
CountedInteger temp = vector[largest];
vector[largest] = vector[p];
vector[p] = temp;
fixDown(vector, largest);
}
}
and here is the error its giving me:
Undefined symbols for architecture x86_64:
"HeapSort::l(int)", referenced from:
vtable for HeapSort in HeapSort.o
"HeapSort::r(int)", referenced from:
vtable for HeapSort in HeapSort.o
"HeapSort::fixDown(std::vector<CountedInteger,std::allocator<CountedInteger>>&,int)",
referenced from:
vtable for HeapSort in HeapSort.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
You're not implementing:
virtual unsigned int l(int i);
virtual unsigned int r(int i);
virtual void fixDown(std::vector<CountedInteger>& vector, int p);
You forgot to qualify these methods in the implementation file.
inline unsigned int l(int i)
is not the same as
inline unsigned int HeapSort::l(int i)
As they are now, they're just free functions defined in that translation unit.
Related
This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 6 years ago.
I have three c++ files, sort.cpp defines a bubble sort function that takes an array, the length of the array and a function that is used to do the comparison. sort.h contains the function prototype inside a namespace. main.cpp is used to test the implementation.
sort.h:
#ifndef SORT_H
#define SORT_H
namespace sort {
template <typename T>
void bubble(T*, int, bool (*)(T, T));
}
#endif
sort.cpp:
#include "sort.h"
template <typename T>
void sort::bubble(T *array, int length, bool (*compare)(T, T)) {
while (length != 0) {
int newLength {0};
for (int i {0}; i < length - 1; ++i) {
if (compare(array[i], array[i+1])) {
T temp {array[i]};
array[i] = array[i+1];
array[i+1] = temp;
newLength = i + 1;
}
}
length = newLength;
}
}
main.cpp:
#include <iostream>
#include "sort.h"
bool larger(int x, int y) {
return x > y;
}
int main() {
int arr[] {3, 5, 1, 3, 7, 2};
sort::bubble(arr, 6, larger);
for(const auto e: arr)
std::cout << e << ' ';
std::cout << '\n';
return 0;
}
When I compile with g++ main.cpp sort.cpp -std=c++11 I get the error
Undefined symbols for architecture x86_64:
"void sort::bubble<int>(int*, int, bool (*)(int, int))", referenced from:
_main in main-767bbd.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Do I get the error because the compiler doesn't know which types I'm going to use when compiling sort.cpp? So the compiler doesn't generate any function off of the template and then the linker can't find it when I use it in main.cpp?
How can I solve this issue?
Don't use two files for templates, just only one: sort.hpp
There is a workaround but is not recommended.
I have a pure virtual function defined in a class as below:
template <typename T>
class PositioningMethod {
public:
virtual ApproximatePosition *getPosition(std::list<T*> &observedRadioSignals) = 0;
};
and implementing it in ParticleFilter as below:
class ParticleFilter:public PositioningMethod<T> {
public:
virtual ApproximatePosition *getPosition(std::list<T*> &observedRadioSignals) {
/*Some code and return*/
return ApproximatePosition::from(xxxx, xxxx, xxxx());
}
};
but getting below errors:
"ParticleFilter<KnownBluetoothBeacon<CartesianLocation>, RadioProximity<BluetoothBeacon>
>::getPosition(std::__1::list<RadioProximity<BluetoothBeacon>*, std::__1::allocator<RadioProximity<BluetoothBeacon>*> >&)", referenced from:
vtable for RadioProximityParticleFilter in lib.a(RadioProximityParticleFilter.o)
"ParticleFilter<KnownBluetoothBeacon<CartesianLocation>, RadioProximity<BluetoothBeacon>
>::ParticleFilter(std::__1::list<KnownBluetoothBeacon<CartesianLocation>, std::__1::allocator<KnownBluetoothBeacon<CartesianLocation> > >&, double)", referenced from:
RadioProximityParticleFilter::RadioProximityParticleFilter(std::__1::list<KnownBluetoothBeacon<CartesianLocation>, std::__1::allocator<KnownBluetoothBeacon<CartesianLocation> > >&, double) in lib.a(RadioProximityParticleFilter.o)
ld: symbol(s) not found for architecture arm64
I know vtable error generally occurs on non-implementing pure virtual functions, but in my case it is same. Any idea where I may be wrong?
Note: The above errors I am getting while integrating my C++ code with objective C in iOS. While in C++ its working fine
This below line is causing the errors in ViewController.mm:
RadioProximityParticleFilter *obj = new RadioProximityParticleFilter (*asList,50);
I completed your code to use it in my MS VS 2013 test project, and it just works - here is the full listing:
#include <iostream>
#include <list>
using namespace std;
class ApproximatePosition
{
public:
static ApproximatePosition *from( int a, int b, int c)
{
cout << "from called." << endl;
return NULL;
}
};
class ListElem{};
template <typename T>
class PositioningMethod
{
public:
virtual ApproximatePosition *getPosition(std::list<T*> &observedRadioSignals) = 0;
};
template <typename T>
class ParticleFilter :public PositioningMethod<T>
{
public:
virtual ApproximatePosition *getPosition(std::list<T*> &observedRadioSignals)
{
/*dummy input and return*/
int a = 0, b = 0, c = 0;
cout << "getPosition called." << endl;
return ApproximatePosition::from( a, b, c );// xxxx, xxxx, xxxx());
}
};
int main()
{
PositioningMethod<ListElem> *pm = new ParticleFilter<ListElem>();
std::list<ListElem*> l;
pm->getPosition( l );
}
The output is:
getPosition called.
from called.
I am compiling a program that uses SFML on android. It compiles normally when I compile it with g++. When I run ndk-build in the android project directory I get the following error:
/home/engineer/Desktop/android_ndk/android-ndk-r11c/toolchains/arm- linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld: the vtable symbol may be undefined because the class is missing its key function (see go/missingkeymethod)
/home/engineer/Desktop/android/jni/SandJar.hpp:16: error: undefined reference to 'vtable for SandJar'
I have an abstract class jar and 2 class sandyJar and sandjar that both inherit it. However, I don't understand why it compiles for g++ but doesnt for the ndk-build command.
Here are some of the source files stripped down(it compiles from main):
Main.cpp:
int main(int argc, char *argv[])
{
sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "");
int WIDTH = window.getSize().x;
int HEIGHT = window.getSize().y;
vector<Jar*> jars;
SandJar SJAR(5,5,5,WIDTH, HEIGHT);
CandyJar CJAR(5,5,5,WIDTH, HEIGHT);
CJAR.add();
CJAR.move(120, 0);
jars.push_back(&CJAR);
jars.push_back(&SJAR);
etc.
}
Jar.hpp
class Jar
{
public:
virtual void add() = 0;
virtual void draw(sf::RenderWindow&) = 0;
virtual void update() = 0;
virtual void move(int,int) = 0;
virtual void setScale(float) = 0;
virtual void incAnim() = 0;
virtual void decAnim() = 0;
};
SandJar.hpp
class SandJar : public Jar
{
public:
//initializer
SandJar(const int, const int, const int, const int, const int);
SandJar(const int);
//function for adding candy
void add();
void update();
void draw(sf::RenderWindow&);
void incAnim();
void decAnim();
void move(int, int);
void setScale(float);
private:
//vars
};
SandJar.cpp
SandJar::SandJar(int Capacity){
}
SandJar::SandJar(int Width, int Height, int Capacity, int WindowW, int WindowH){
}
void SandJar::init() {
}
void SandJar::incAnim() {
}
void SandJar::decAnim() {
}
void SandJar::move(int x, int y)
{
}
void SandJar::setScale(float scl)
{
}
void SandJar::update() {
}
void SandJar::add() {
}
void SandJar::draw(sf::RenderWindow& window) {
}
As it turns out there was no problem with any of the code. The problem was the Android.mk file used for the project. I appended the hpp and cpp files to LOCAL_SRC_FILES and it built correctly. It says not to include "includes" in LOCAL_SRC_FILES but once added it compiled correctly. There may be a better fix.
I am writing a simple server program using ICE by ZeroC. When I try to link the .o files it gave me the following error message:
$ c++ -o server UserMap.o Server.o -L/Library/Developer/Ice-3.5.0/lib -lIce -lIceUtil
Undefined symbols for architecture x86_64:
"VTT for UserMapI", referenced from:
UserMapI::UserMapI() in Server.o
"vtable for UserMapI", referenced from:
UserMapI::UserMapI() in Server.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
After some googling I understand that the problem is I have an abstract class with 3 virtual methods declared in UserMap.ice (and hence in UserMap.h and UserMap.cpp generated by the command slice2cpp UserMap.ice), and in Server.cpp I have a class called UserMapI:public UserMap which implements the three virtual methods and another private helper function. The error is generated because the compiler thinks I have declared all functions(methods) in UserMap.h and UserMap.cpp.
My understanding to this problem is that I should modify the link command so that the linker will know that there are more functions in UserMapI declared in Server.cpp, but I don't have enough knowledge to do the modification. Can someone help me please?
Thank you all.
Here is the compiler command I am using to get Server.o and UserMap.o:
c++ -I. -I/Library/Developer/Ice-3.5.0/include -c UserMap.cpp Server.cpp
Here's the code of UserMap.ice:
module DR
{
class UserMap
{
void addUserToLocation(int userID, int x, int y);
string getUsersNearLocation(int x, int y, int distance);
void removeFromMap(int userID, int x, int y);
};
};
slice2cpp command slices this .ice file into a .h and a .cpp file that works as an API between server and client.
In Server.cpp I have the following include:
#include <Ice/Ice.h>
#include "UserMap.h"
#include <map>
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
and the following subclass:
class UserMapI : public UserMap
{
public:
virtual void addUserToLocation(int userID, int x, int y, const Ice::Current &);
virtual string getUsersNearLocation(int x, int y, int distance, const Ice::Current &);
virtual void removeFromMap(int userID, int x, int y, const Ice::Current &);
private:
string stringify(int x, int y);
};
And after implementing all methods here's the main function:
int main(int argc, char* argv[])
{
int status = 0;
Ice::CommunicatorPtr ic;
try {
ic = Ice::initialize(argc, argv);
Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithEndpoints("SimpleUserMapAdapter", "default -p 10000");
Ice::ObjectPtr object = new UserMapI;
adapter->add(object, ic->stringToIdentity("SimpleUserMap"));
adapter->activate();
ic->waitForShutdown();
} catch (const Ice::Exception & e) {
cerr << e << endl;
status = 1;
} catch (const char * msg) {
cerr << msg << endl;
status = 1;
}
if (ic){
try {
ic->destroy();
} catch (const Ice::Exception & e) {
cerr << e << endl;
status = 1;
}
}
return status;
}
Here's the UserMap.h.
My code is:
class cMySingleton{
private:
static bool bInstantiated;
int mInt;
cMySingleton(){
mInt=0;
}
public:
cMySingleton(int c){
if (bInstantiated){
cout << "you can only instantiated once";
}
else {
cMySingleton();
mInt=c;
}
}
};
int main () {
cMySingleton s(5);
cMySingleton t(6);
}
The linker keeps complaining:
Undefined symbols for architecture x86_64:
"cMySingleton::bInstantiated", referenced from:
cMySingleton::cMySingleton(int) in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
What is going on? C++ novice here~~
you should initialize static field.
http://ideone.com/Y1huV
#include <iostream>
class cMySingleton{
private:
static bool bInstantiated;
int mInt;
cMySingleton(){
mInt=0;
}
public:
cMySingleton(int c){
if (bInstantiated){
std::cout << "you can only instantiated once";
}
else {
cMySingleton();
mInt=c;
}
}
};
bool cMySingleton::bInstantiated = true;
int main () {
cMySingleton s(5);
cMySingleton t(6);
}
More information you can be find here:
Static Data Member Initialization
there was also missing include and std:: around cout.
Initialize
static bool bInstantiated;
outside of cMySingleton
bool CMySingleton::bInstantiated;
Dont forget to initialize your static member outside of your class declaration in .cpp file:
bool cMySingleton::bInstantiated = false;