vtable C++ error after implementing pure virtual method - c++

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.

Related

Vscode terminal message

I use mac vscode, and try to run the following file. When the error message pops up, the phrases are partially strange and not meaningful. Is there a way to change setting of vscode so that the output of my error message becomes normal again, something like Parent.class, Parent.h ... instead of Zn3_Parent...?
Below is the code I run:
#include <iostream>
using namespace std;
class Parent {
public :
virtual int func () = 0;
virtual ~Parent();
};
class Child : public Parent {
public :
int data;
Child (int k) {
data = k;
}
int func() { // virtual function
cout<<"Returning square of 10\n";
return 10*10;
}
void Display () {
cout<<data<<"\n";
}
~ Child() {
cout<<"Overridden Parents Destructor \n";
}
};
int main() {
Child a(10);
a.Display();
//cout << "asdf";
return 1;
}
And the output I get:
Undefined symbols for architecture x86_64:
"__ZN6ParentD2Ev", referenced from:
__ZN5ChildD1Ev in ccn2pmId.o
"__ZTI6Parent", referenced from:
__ZTI5Child in ccn2pmId.o
"__ZTV6Parent", referenced from:
__ZN6ParentC2Ev in ccn2pmId.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
collect2: error: ld returned 1 exit status
I don't want those things like __ZN6, ZTI6, ZTV6.

initialize map with static member variable

I do not understand why I cannot use a public const static member of a class in the initializer list of a map (probably any container). As I understand it "MyClass::A" is an rvalue, it seems like it should be the exact same as the case where I am using "THING" which is also a static const just outside of a class.
Here is the error:
Undefined symbols for architecture x86_64:
"MyClass::A", referenced from:
_main in map-380caf.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
And here is the code:
#include <iostream>
#include <map>
#include <string>
static const int THING = 1;
class MyClass {
public:
static const int A = 1;
};
int
main()
{
int a;
typedef std::map<int, std::string> MyMap;
// compiles and works fine
a = MyClass::A;
std::cout << a << std::endl;
// compiles and works fine
MyMap other_map = { {THING, "foo"} };
std::cout << other_map.size() << std::endl;
// Does not compile
MyMap my_map = { {MyClass::A, "foo"} };
std::cout << my_map.size() << std::endl;
return 0;
}
UPDATE 1:
Using clang on OS X:
Apple LLVM version 7.0.0 (clang-700.0.72)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
compiler flags:
clang++ map.cc -std=c++1y
Something in the map code probably tried to take the address of a reference to your int.
The class definition here:
class MyClass {
public:
static const int A = 1;
};
does not actually create any memory for A. In order to do that you have to do in the header file:
class MyClass {
public:
static const int A;
};
and in a CPP file:
const int MyClass::A = 1;
Or I guess with the newest C++ versions you can leave the = 1 in the header and just declare the storage in the CPP file with:
const int MyClass::A;

C++11 vector of shared_ptr template

I am trying to call the following function template:
template<typename T>
bool select(const std::string& ddbbName,
const std::string& sql,
std::vector<std::shared_ptr<T>>& vResultSet,
SqlErrorInfo& errorInfo);
which is defined in a class whose name is SQLite3Manager. In the following code this "select" method does nothing (a part from returning "true"). I have tried to simplify the problem description, because the problem seems to be related to the way I am calling/using/defining that method.
So the main.cpp code is:
main.cpp
#include <iostream>
#include "ES.h"
#include "SQLiteMgr.h"
int main(int argc, const char * argv[])
{
// To get an instance of the singleton
Cucut::SQLite3Manager& _sqliteMgr = Cucut::SQLite3Manager::getInstance();
std::string ddbbName("Cucut.db");
std::string sql("SELECT * FROM ES");
std::vector<std::shared_ptr<Cucut::ES>> vspEs;
Cucut::SqlErrorInfo sqlErrorInfo;
// Call the template method for <Cucut::ES> using the instance of the singleton
bool result = _sqliteMgr.select<Cucut::ES>(ddbbName, sql, vspEs, sqlErrorInfo);
return result;
}
but I get the following link error in Xcode 5:
Undefined symbols for architecture x86_64:
"bool Cucut::SQLite3Manager::select<Cucut::ES>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<std::__1::shared_ptr<Cucut::ES>, std::__1::allocator<std::__1::shared_ptr<Cucut::ES> > >&, Cucut::SqlErrorInfo&)", referenced from:
_main 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)
The full code is:
ES.h file:
#ifndef __TestSharedPtr__ES__
#define __TestSharedPtr__ES__
#include <iostream>
namespace Cucut
{
class ES
{
public:
ES();
const unsigned int& getId() const;
void setId(const unsigned int& id);
private:
unsigned int _id;
};
}
#endif /* defined(__TestSharedPtr__ES__) */
ES.cpp file:
#include "ES.h"
namespace Cucut
{
ES::ES() :
_id(0)
{
}
const unsigned int& ES::getId() const
{
return _id;
}
void ES::setId(const unsigned int& id)
{
_id = id;
}
}
SQLiteMgr.h file:
#ifndef __TestSharedPtr__SQLiteMgr__
#define __TestSharedPtr__SQLiteMgr__
#include <iostream>
#include <vector>
#include <memory>
namespace Cucut
{
struct SqlErrorInfo
{
int rc;
std::string description;
};
class SQLite3Manager
{
private:
SQLite3Manager();
SQLite3Manager(const SQLite3Manager& rs);
SQLite3Manager(SQLite3Manager&& rs);
SQLite3Manager& operator = (const SQLite3Manager& rs);
SQLite3Manager& operator = (SQLite3Manager&& rs);
public:
static SQLite3Manager& getInstance();
template<typename T>
bool select(const std::string& ddbbName,
const std::string& sql,
std::vector<std::shared_ptr<T>>& vResultSet,
SqlErrorInfo& errorInfo);
};
}
#endif /* defined(__TestSharedPtr__SQLiteMgr__) */
And finally the SQLiteMgr.cpp file:
#include <memory>
#include <vector>
#include "SQLiteMgr.h"
namespace Cucut
{
SQLite3Manager::SQLite3Manager()
{
}
SQLite3Manager& SQLite3Manager::getInstance()
{
static SQLite3Manager instance;
return instance;
}
template<typename T>
bool SQLite3Manager::select(const std::string& ddbbName,
const std::string& sql,
std::vector<std::shared_ptr<T>>& vResultSet,
SqlErrorInfo& errorInfo)
{
return true;
}
}
Do not be distract with the name "SqliteMgr" because in the aforementioned example I have removed any kind of reference to sqlite3 in order to simplify the problem; so, it seems that I am not calling or defining the method "select" in the correct way because I get the aforementioned link error.
Any help will be appreciated. Thanks in advance.
Function template definitions must always be in the header file so that code can be generated at the point of instantiation (here in main). If you don't do this, the compiler will expect you to manually instantiate the template, which is why there is a linker error. Move the body of the select function to SQLiteMgr.h and it will work.

XCode Linker Error, Simple C++ functions

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.

why the following code compiles fine but linking shows error when use static

The following code compiles fine. but when goes to linking,
it shows following error
Undefined symbols for architecture x86_64:
"derived::counter", referenced from:
derived::getAddressCounter() in main.cpp.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
I suspect there is something wrong with the static. but not sure why. Because once I take out the static, the code links fine. But how does static plays any role in this code?
#include <iostream>
#include <string>
struct base_result { };
struct result : public base_result {
int a;
std::string b;
};
struct base {
static base_result counter;
};
struct derived: public base {
static result counter;
result * getAddressCounter(){
counter.a = 10;
counter.b = "haha";
return &counter;
}
};
int main (){
derived d;
result * ptr;
ptr = d.getAddressCounter();
ptr->a = 20;
ptr->b = "baba";
std::cout << ptr->a << std::endl;
std::cout << ptr->b << std::endl;
return 0;
}
struct base
{
static base_result counter;
};
Only declares the static member, You also need to define it once in your cpp file.
Good Read:
What is the difference between a definition and a declaration?
In contrast to member variables which get a reserved space in every created object, static variables can't just be declared, they need to be implemented/defined too.
Just add the lines
base_result base::counter;
result derived::counter;
to your code and it will compile just fine. Those lines instructs the compiler to actually reserve space to store the static variables you declared earlier.