Undefined reference to Class even though I compiled all cpp files - c++

first of all I am kind of new to coding, so it might be that I just missed something really obvious. Still I would appreciate any help.
I created some header and some code files in one directory, namely "main.cpp","elements.cpp","queue.cpp", "elements.hpp" and "queue.hpp". In "main.cpp" I included both .hpp files.
Then I compiled: g++ main.cpp elements.cpp queue.cppto get an executable file with all three .cpp files linked.
Still I get the following error message /usr/bin/ld: /tmp/ccUjQcqj.o: in function main': main.cpp:(.text+0x33): undefined reference to Queue::Queue()'.
Queue is a class declared in "queue.hpp".
Here is the code for "queue.hpp":
#include "elements.hpp"
class Queue{
Element Q[10];
int start;
int count;
void print(bool dir,int count);
public:
Queue(); //Standard Konstruktor Deklaration
void push(Element e);
void pop();
Element& top();
void print(bool dir=true);
int size();
};
Here is the code for "queue.cpp":
#include "elements.hpp"
#include <iostream>
class Queue{
Element Q[10];
int start;
int count;
void print(bool dir,int count){
if(count>0 && dir==0){
Q[count-1].print();
print(dir,count-1);
}
if(count>0 && dir==1){
print(dir,count-1);
Q[count-1].print();
}
}
public:
Queue():start(0),count(0){}
void push(Element e){
if (count==10){
for(int i=0;i<9;i++){
Q[i]=Q[i+1];
}
Q[9]=e;
}
else{Q[start+count]=e;
count++;
}}
void pop(){
for(int i=0;i<9;i++){
Q[i]=Q[i+1];
}
count--;
}
Element& top(){
return Q[0];
}
void print(bool dir=true){
print(dir,count);
}
int size(){
return count;
}
};
I do not understand why there is an undefined reference here, since I included "queue.hpp" in main and the constructor in "queue.cpp" is also not missing.
Thank you for your help!

Related

how to properly include .h, and .tpp

I have the following project structure:
This a handler for the "IOPin" class:
//IOPinHandler class
//IOPinHandler.h
#include <type_traits>
class IOPin; //forward declaration required
class IOPinHandler
{
public:
explicit IOPinHandler() { }
virtual ~IOPinHandler() { }
void checkBool(const bool& b);
void checkInt(const int& b);
template<typename T>
void modifyIOPinMember(IOPin& ioPin, const T& param);
};
//To avoid multiple definitions
#ifndef _OD_
void IOPinHandler::checkBool(const bool& b)
{
//Do stuff
}
void IOPinHandler::checkInt(const int& b)
{
//Do stuff
}
#endif
The following is the .tpp file for the definition of modifyIOPinMember member.
//IOPinHandler class
//IOPinHandler.tpp
template<typename T>
void IOPinHandler::modifyIOPinMember(IOPin& ioPin, const T& param)
{
if constexpr(std::is_same_v<T, int>)
{
checkInt(param);
ioPin.m2 = param;
}
else if constexpr(std::is_same_v<T, bool>)
{
checkBool(param);
ioPin.m1 = param;
}
}
The following is the "IOPin" class, the one meant to be handled by the class above. Since IOPinHandler's modifyIOPinMember member requires to know the definition of "IOPin" (its complete type) then, the IOPinHandler.tpp file is included in IOPin.h file as follows:
//IOPin class
//IOPin.h
//To avoid multiple definitions
#define _OD_
#include "IOPinHandler.h"
class IOPin
{
public:
explicit IOPin(const bool& b, const int& n):m1(b), m2(n) { _handler = new IOPinHandler; }
void setInt(const int& n) { _handler->modifyIOPinMember(*this, n); }
void setBool(const bool& b) { _handler->modifyIOPinMember(*this, b); }
private:
bool m1{false};
int m2{0};
IOPinHandler* _handler{nullptr};
friend class IOPinHandler;
};
#include "IOPinHandler.tpp"
The problem is that calling either setInt or SetBool methods, result in a compile time error:
//main.cpp
#include "IOPin.h"
IOPin a(false, 0);
int main()
{
a.setInt(89);
a.setBool(true);
return 0;
}
This is the error:
/usr/bin/ld: /tmp/ccpKv7HW.o: in function `void IOPinHandler::modifyIOPinMember<int>(IOPin&, int const&)':
main.cpp:(.text._ZN12IOPinHandler17modifyIOPinMemberIiEEvR5IOPinRKT_[_ZN12IOPinHandler17modifyIOPinMemberIiEEvR5IOPinRKT_]+0x27): undefined reference to `IOPinHandler::checkInt(int const&)'
/usr/bin/ld: /tmp/ccpKv7HW.o: in function `void IOPinHandler::modifyIOPinMember<bool>(IOPin&, bool const&)':
main.cpp:(.text._ZN12IOPinHandler17modifyIOPinMemberIbEEvR5IOPinRKT_[_ZN12IOPinHandler17modifyIOPinMemberIbEEvR5IOPinRKT_]+0x27): undefined reference to `IOPinHandler::checkBool(bool const&)'
collect2: error: ld returned 1 exit status
What am I missing over here?
I know that a solution is to create a "IOPinHandler.cpp" file and put there the definitions for "checkBool" and "checkInt" methods, however I dont want to have a separate .cpp file only for that.
Thanks in advance.
In C++, we almost never include the implementation file, only header (.h) files; and, if your class is templated, all class's function implementations should be in header only; no secondary file is needed or advised, and you should always use header guards for your header files, used as follows:
#ifndef ANY_UNIQUE_NAME // recommended related to header file name
#define ANY_UNIQUE_NAME
//#includes <...>
//header code
#endif
Then you include headers when you need them.

Why is my c++ singleton not working on Clion?

I want to have a singleton in my project but some errors occur
this is my codes in three separate files.:
//---------------My main.cpp code
#include <iostream>
#include "Sports/BBVB.h"
int main() {
bbvb;
return 0;
}
// ---------------------------my BBVB.h code
#ifndef SAMAVAR_BBVB_H
#define SAMAVAR_BBVB_H
typedef struct VBResult{
int set1=-1;
int set2=-1;
int set3=-1;
int set4=-1;
int set5=-1;
}VBResult;
#include "Sport.h"
#include "../TournamentStuf/Tournament.h"
class BBVB: public Sport {
protected:
vector<Tournament<VBResult>> tours;
public:
static BBVB& getInstance(){
static BBVB b;
return b;
}
private:
BBVB(){}
public:
BBVB(BBVB const&)=delete;
void operator=(BBVB const&) = delete;
//-------------Setter------------
//------------Getter-------------
vector<Tournament<VBResult>> getTours() const;
Tournament<VBResult> getTourById(int id) const;
//----------Others---------------
void addTour(Tournament<VBResult> v);
};
BBVB &bbvb=BBVB::getInstance();
#endif //SAMAVAR_BBVB_H
//------------------my Store and restore code
#ifndef SAMAVAR_STOREANDRESTORE_H
#define SAMAVAR_STOREANDRESTORE_H
#include "../Sports/BBVB.h"
#include "../Sports/PingPong.h"
#include "../Sports/Wrestling.h"
void Start(BBVB &b);
void Update(const BBVB &b);
void Start(PingPong &p);
void Update(const PingPong &p);
void Start(Wrestling &w);
void Update(const Wrestling &w);
#endif //SAMAVAR_STOREANDRESTORE_H
I have a bbvb instance of BBVB but it says you have multiple definitions of it.
I'm new to Clion and I don't have enough information about somethings like cmake and I feel the problem is because of it.
I want to have something like cout and cin in iostream.so by including my BBVB I can access this object.
Clion shows error below:
CMakeFiles\Samavar.dir/objects.a(BBVB.cpp.obj):BBVB.cpp:(.bss+0x0): multiple definition of `bbvb'
CMakeFiles\Samavar.dir/objects.a(main.cpp.obj):main.cpp:(.bss+0x0): first defined here
CMakeFiles\Samavar.dir/objects.a(StoreAndRestore.cpp.obj):StoreAndRestore.cpp:(.bss+0x0): multiple definition of `bbvb'
CMakeFiles\Samavar.dir/objects.a(main.cpp.obj):Samavar-master/Sports/BBVB.h:24: first defined here
collect2.exe: error: ld returned 1 exit status

C++ Compiler errors

I'm writing a c++ stack and queue implementation program, I finished the stack part, but when compiling I'm getting these errors
arrayListImp.cpp:18:19: error: expected unqualified-id
arrayList[++top]= x;
^
arrayListImp.cpp:28:13: error: 'arrayList' does not refer to a value
itemPoped=arrayList[top];
^
./arrayList.h:3:7: note: declared here
class arrayList{
^
arrayListImp.cpp:35:9: error: 'arrayList' does not refer to a value
return arrayList[top];
^
./arrayList.h:3:7: note: declared here
class arrayList{
^
arrayListImp.cpp:46:9: error: 'arrayList' does not refer to a value
cout<<arrayList[i]<<endl;
^
./arrayList.h:3:7: note: declared here
class arrayList{
^
4 errors generated.
Here is the header file
#ifndef ARRAYLIST_H
class arrayList{
public:
arrayList();
static const int maxSize = 10;
int array[10];
};
class stack : public arrayList{
public:
stack();
void push(int x);
void pop();
int Top();
int isEmpty();
void print();
int x;
int top;
int itemPoped;
int i;
};
#define ARRAYLIST_H
#endif
arrayListImp.cpp
#include <iostream>
#include "arrayList.h"
using namespace std;
//Stack implementation
stack::stack(){
top = -1;
}
void stack::push(int x){
if (top == maxSize -1){
cout<<"Stack overflow"<<endl;
}
else{
arrayList[++top]= x;
cout<<x<<", is pushed on to the stack"<<endl;
}
}
void stack::pop(){
if (top == -1){
cout<<"Stack underflow"<<endl;
}
else{
itemPoped=arrayList[top];
top--;
cout<<itemPoped<<", is poped from the stack"<<endl;
}
}
int stack::Top(){
return arrayList[top];
}
int stack::isEmpty(){
if (top == -1) return 1;
return 0;
}
void stack::print(){
cout<<"Stack: "<<endl;
for (i = 0; i<=top; i++){
cout<<arrayList[i]<<endl;
}
}
arrayListUse.cpp
#include <iostream>
#include "arrayList.h"
using namespace std;
int main()
{
//Stack testing
stack S;
S.push(1);S.print();
S.push(2);S.print();
S.push(3);S.print();
S.pop();S.print();
S.push(4);S.print();
//Queue testing
return 0;
}
Can you please point out to what I'm doing wrong here?
You should just read your error messages.
You should use array instead of arrayList, which is the name of the class. So just refer to the variable instead.
The error message you got is something like
test.cpp: In member function ‘void stack::push(int)’:
test.cpp:44:18: error: expected unqualified-id before ‘[’ token
arrayList[++top]= x;
^
When you check the line, you immediately see what is wrong there.
You declare a constructor arrayList::arrayList(), but you do not define it. Either you can drop the declaration, or you should implement it in the cpp-file.
arrayList::arrayList() {
// do some initialization
}
The error message you got is something like
/tmp/cc4y06YN.o:test.cpp:function stack::stack(): error: undefined reference to 'arrayList::arrayList()'
The code could compile, but it did not link. So all declarations may be correct, but a symbol was missing. This is usually the case when you declared something you referred to, but you never defined it.
You always have written
arrayList[...]
what is the name of your class but reading the code it seems like you wanted to write
array[...]
which would access the data.

Undefined reference to vtable SFML Android

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.

Problems accessing private data members c++

I have three files: Stack.cc, Stack.h and stacktest.cc . I am not sure about which files to include where, and i am getting different errors because of it. Currently, the code from Stack.h is:
#ifndef STACK_H
#define STACK_H
#include<iostream>
using namespace std;
template<typename T>
class Stack
{
public:
Stack();
void push(int);
void pop();
int top();
int size();
bool empty();
private:
class Element
{
public:
int data;
Element *next;
Element(Element *n, T d) : next{n}, data{d} {}
};
Element *first;
int num;
};
#endif
#include"Stack.cc"
the (relevant, i think) code from Stack.cc is:
#include<iostream>
using namespace std;
template<typename T>
Stack<T>::Stack()
{
first=nullptr;
}
template<typename T>
void Stack<T>::push(int)
{
num++;
first = new Element(first, data);
}
Stacktest is currently just a test file attempting to call the default constructor. The errors i currently get are:
In file included from Stack.h:30:0,
from stacktest.cc:2:
Stack.cc: In member function ‘void Stack<T>::push(int)’:
Stack.cc:22:28: error: ‘data’ was not declared in this scope
first = new Element(first, data);
^
Stack.cc: In function ‘int size()’:
Stack.cc:62:11: error: ‘num’ was not declared in this scope
return num;
For some reason it wont let me access private data members. Before i didnt have the include in the .h file and instead included the .h in Stack.cc, and that worked, although wouldnt let me access the stack class from Stacktest.cc(Stacktest.cc just includes Stack.h)
Any help would be greatly appreciated, thanks.