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

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

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.

Strange "Undefined reference" error on C++ Netbeans project [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 7 years ago.
The solution to the duplicate question did not work
I have the following files:
ListaEnc.hpp
#include "Elemento.hpp"
template<typename T>
class ListaEnc {
public:
ListaEnc();
~ListaEnc();
// inicio
void adicionaNoInicio(const T& dado);
T retiraDoInicio();
void eliminaDoInicio();
T pegarHead();
// posicao
void adicionaNaPosicao(const T& dado, int pos);
int posicao(const T& dado) const;
T* posicaoMem(const T& dado) const;
bool contem(const T& dado);
T retiraDaPosicao(int pos);
// fim
void adiciona(const T& dado);
T retira();
// especifico
T retiraEspecifico(const T& dado);
void adicionaEmOrdem(const T& data);
// outras
bool listaVazia() const;
bool igual(T dado1, T dado2);
bool maior(T dado1, T dado2);
bool menor(T dado1, T dado2);
void destroiLista();
int pegarTamanhoLista();
private: //trocar pra private
Elemento<T>* head;
int size;
};
ListaEnc.cpp
#include "ListaEnc.hpp"
#include <cstdlib>
#include <iostream>
template<typename T>
ListaEnc<T>::ListaEnc()
{
...
}
main.cpp
#include "ListaEnc.hpp"
using namespace std;
int main(int argc, char** argv)
{
double x1, y1;
x1 = 2; y1 = 4.2;
ListaEnc<int>* teste = new ListaEnc<int>();
return 0;
}
This should compile just fine, but I get an undefined reference error to ListaEnc on main.cpp. I have more files in which the reference to ListaEnc is also undefined, but I tried isolating it and still can't get it to work. Does anyone understand why this is happening?
edit: More specifically, there is an undefined error to the constructor and destructor of ListaEnc
You can't separate declaration from implementation when you instantiate a template class. Combine your code to a single file and include that in your main.cpp.
Or, even go a step further and implement the functions inline in your class declaration if that suits your coding style.

Arduino C++ file - class instantiation fails when setting a private member variable in the constructor

I'm using the Arduino IDE 1.0.5-r2 and trying to create a class with two member variables, _pinA and _pinB. When I call the constructor from my Arduino sketch, I get this error:
RotaryEncoderReader.cpp:6: error: request for member '_pinB' in 'this', which is of non-class type 'RotaryEncoderReader* const'
The constructor can be called from a regular C++ files compiled using GCC, and there are no errors. Am I missing something about how to use a class constructor with an Arduino?
Here is the class header:
#ifndef RotaryEncoderReader_h
#define RotaryEncoderReader_h
#include "Arduino.h"
class RotaryEncoderReader {
private:
int _pinA;
int _pinB;
volatile long encoderPos;
public:
RotaryEncoderReader( int newPinA, int newPinB );
void doEncoderA();
void doEncoderB();
long getPosition();
};
#endif
Here's the implementation:
#include "RotaryEncoderReader.h"
RotaryEncoderReader::RotaryEncoderReader( int newPinA, int newPinB )
: _pinA(newPinA),
_pinB(newPinB),
encoderPos(0)
{
}
void RotaryEncoderReader::doEncoderA()
{
//Irrelevant
}
void RotaryEncoderReader::doEncoderB()
{
//Irrelevant
}
long RotaryEncoderReader::getPosition()
{
return _pinA + _pinB;
}
And here's the Arduino sketch:
#include <RotaryEncoderReader.h>
int pinA = 2;
int pinB = 3;
RotaryEncoderReader reader(pinA, pinB);
void setup()
{
}
void loop()
{
}

undefined reference to `typeinfo and 'vtable

i'm currently working on a program that employs the user of virtual functions. I am using only one virtual function and have come across what seems to be a common problem with a common solution which I have tried but unfortunately to no success.
I originally had virtual void calcArea(); in BasicShape.h without any definition or designation as a pure virtual function. I changed it and added {} at the end (as suggested on another thread with a similar problem) but I still get the following error:
I input:
g++ BasicShape.h BasicShape.cpp circle.h circle.cpp Rectangle.h Rectangle.cpp driver.cpp -o Lab4
And then I get:
/tmp/ccf1Y4Br.o: In function `BasicShape::BasicShape()': circle.cpp:(.text._ZN10BasicShapeC2Ev[_ZN10BasicShapeC5Ev]+0xf): undefined reference to `vtable for BasicShape'
/tmp/ccf1Y4Br.o:(.rodata._ZTI6circle[_ZTI6circle]+0x10): undefined reference to `typeinfo for BasicShape'
/tmp/ccc7gjtH.o:(.rodata._ZTI9Rectangle[_ZTI9Rectangle]+0x10): undefined reference to `typeinfo for BasicShape'
collect2: error: ld returned 1 exit status
Any ideas?
This is the implementation file BasicShape.h:
#ifndef BASICSHAPE_H
#define BASICSHAPE_H
class BasicShape
{
protected:
double area;
public:
double getArea() const;
virtual void calcArea();
};
#endif
The accompanying BasicShape.cpp file:
#include "BasicShape.h"
double BasicShape::getArea() const
{
return area;
}
void BasicShape::calcArea()
{
}
circle.h:
#include "BasicShape.h"
#ifndef CIRCLE_H
#define CIRCLE_H
class circle : public BasicShape
{
private:
long centerX;
long centerY;
double radius;
public:
circle(long, long, double);
long getCenterX() const;
long getCenterY() const;
virtual void calcArea();
};
#endif
circle.cpp:
#include "circle.h"
// constructor
circle::circle(long userIn, long userIn2, double userIn3)
{
centerX = userIn;
centerY = userIn2;
radius = userIn3;
calcArea();
}
// accesors
long circle::getCenterX() const
{
return centerX;
}
long circle::getCenterY() const
{
return centerY;
}
// virtual function
void circle::calcArea()
{
area = (3.14159 * radius * radius);
}
Rectangle.h
#include "BasicShape.h"
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle : public BasicShape
{
private:
long width;
long length;
public:
Rectangle(long, long);
long getWidth() const;
long getLength() const;
virtual void calcArea();
};
#endif
Rectangle.cpp:
#include "Rectangle.h"
// constructor
Rectangle::Rectangle(long userIn, long userIn2)
{
width = userIn;
length = userIn2;
calcArea();
}
// accessors
long Rectangle::getWidth() const
{
return width;
}
long Rectangle::getLength() const
{
return length;
}
void Rectangle::calcArea()
{
area = (length * width);
}
The driver program is incomplete, but irrelevant to my problem anyway (at least I think so).
#include <cassert>
#include <iostream>
#include "BasicShape.h"
#include "Rectangle.h"
#include "circle.h"
using namespace std;
int main()
{
cout << "Testing the functionality and efficiency of the circle class...\n";
// declare circle object and test accessors and area computation
circle objCircle(8,8,4);
assert(objCircle.getCenterX() == 8);
assert(objCircle.getCenterY() == 8);
assert(objCircle.getArea() == 50.26544);
cout << "Circle object testing completed successfully\n";
cout << "Testing the functionality and efficiency of the Rectangle class...\n";
// declare rectangle object and test accessors and area computation
//Rectangle objRec();
return 0;
}
Actually, as it was pointed out, you have not to compile headers. (Although you can, it is irrelevant here --- gcc will generate precompiled headers).
And more interesting: your example perfectly works here, GCC 4.6.3.
Also, sidenote: calcArea shouldn't be public
You should not tryo to compile the headers:
g++ BasicShape.cpp circle.cpp Rectangle.cpp driver.cpp -o Lab4
Your compiler needs at least one translation unit where a virtual member is defined outside the class definition for each polymorphic class. It will instantiate some internal data for the class (virtual function table, polymorphic typeinfo) only if there is such a translation unit.
(Disclaimer: At least that was the case when I last used it, long ago)
You could either use an out-of-class definition for the BasicShape::calcArea function or add a virtual (optionally even pure virtual) destructor to BasicShape and define it out-of-class. The best place would probably be the BasicShape.cppfile.
BTW: As others have pointed out, you typically should not pass header files as separate translation units to the compiler. This will do no harm (other than inflate your compilation time), but also no good.
Ok, so apparently this all seems to be a compiler issue. This entire time I was using gedit as a text editor and g++ as a compiler, but when I switched over to code blocks it was working just fine.

Function and Class errors

class BufferFile{
public:
BufferFile(IOBuffer &);
int Open(char *);
int Create(char *);
int Close();
int Rewind();
int Read(int recaddr = -1);
int Write(int recaddr = -1);
int Append();
IOBuffer & GetBuffer();
protected:
IOBuffer & Buffer;
std::fstream File;
int HeaderSize;
int ReadHeader();
int WriteHeader();
};
BufferFile::BufferFile(IOBuffer & from):Buffer(from){}
int BufferFile::Read(int recaddr){
if(recaddr==1) return Buffer.Write(File);
else return Buffer.DWrite(File, recaddr);
}
int BufferFile::Append(){
File.seekp(0,std::ios::end);
return Buffer.Write(File);
}
IOBuffer & BufferFile::GetBuffer(){
return Buffer;
}
int BufferFile::ReadHeader(){
return Buffer.ReadHeader(File);
}
int BufferFile::WriteHeader(){
return Buffer.WriteHeader(File);
}
I am getting several errors form the IOBuffer field, saying that it was not declared in the function scopes or "expected `)' before ‘&’ token" on the constructor, what is causing these?
Here are all the files involved in this project:
Person.h!
Buffile.cpp
BuffFile.h
Delim.cpp
Delim.h
Fixfld.cpp
Fixfld.h
FixLen.cpp
FixLen.h
Iobuffer.cpp
Iobuffer.h
Length.cpp
Length.h
Varlen.cpp
Varlen.h
I think your problem is this (from Buffile.h):
#ifndef IOBUFFER
#define IOBUFFER
#include "Iobuffer.h"
#endif
... that logic breaks the similar/redundant logic that you have in Iobuffer.h:
#ifndef IOBUFFER
#define IOBUFFER
class IOBuffer{
[...]
#endif
The problem is that the declaration of "class IOBuffer" in Iobuffer.h is never parsed, because the compiler value IOBUFFER was already defined inside Buffile.h, and thus the #ifndef IOBUFFER at the top of Iobuffer.h is not activated.
The right way to do it is to modify Buffile.h to include only the #include "Iobuffer.h" line, and leave it up to the contents of Iobuffer.h to do the #ifndef and #define stuff.