C++ preprocessor directive issue - c++

I have a stream class with following functions :
void writeInt(int value); //old function
void writeInt(int value, char* lable); //new function
we've used the writeInt() old function in lot of places. without changing the existing usage
I tried to replace the old function with the new function using following:
#define writeInt(x) writeInt(x,#x)
but it still calls the old functions not the new functions!.
Update:(working test-case)
// IStream.h
#include <stdio.h>
class IWStream {
public:
IWStream(char* path);
virtual ~IWStream();
virtual void writeInt( int iValue, char* szlable= 0 );
private:
FILE* _file;
};
//DataObject.h
class DataObject {
public:
DataObject(int value);
virtual ~DataObject(){};
void writeData(IWStream *stream);
private:
int _value;
};
//DataObject.cpp
#include "DataObject.h"
#include "IStream.h"
#define writeInt(x) writeInt(x,#x)
DataObject::DataObject(int value)
{
_value = value;
}
void DataObject::writeData(IWStream *stream)
{
stream->writeInt(_value);
}
//main.cpp
int main(){
IWStream stream("D://test.txt");
DataObject data(10);
data.writeData(&stream);
return 0;
}

Related

How to pass smart pointer instead of "this" in C++ 11?

I am using c++11 compiler.
I have two classes - class Test and class TestHelper.
The class Test is a friend-to-class TestHelper.
The class Test is only which we can access from outside.
Now, we want to call Test API i.e. setVal(). This setVal() should call
Test2 API i.e. setX and is expecting this pointer. I don't want to use this pointer but want
to use a smart pointer instead. How can I do so?
The notion of this kind of desirability is because of the fact that in reality, my class Test is pretty big. So, I am trying to make a helper class for Test i.e.
class TestHelper;
class Test
{
friend class TestHelper;
int x;
public:
void display() {
std::cout << x;
}
void setVal(int val) {
TestHelper testH;
testH.setX(this, 324);
}
};
class TestHelper
{
public:
void setX(Test *test, int val) {
/** some algorithm here and then change val to something else */
test->x = val*100;
}
};
int main()
{
std::cout << "Hello World!\n";
Test x;
x.setVal(130);
}
I tried changing the prototype from void setX(Test *test, int val)
to void setX(std::shared_ptr<Test> test, int val) but don't know how to pass this pointer
as std::shared_ptr<Test> test here.
So here is working solution with shared pointers. The example doesn't even compile due to missing definitions so you have to restructure your code into headers and cpp files.
Test.h:
#ifndef TEST_H
#define TEST_H
#include <memory>
#include "TestHelper.h"
class Test : public std::enable_shared_from_this<Test>
{
private:
friend class TestHelper;
int x;
public:
void display();
void setVal(int val);
};
#endif
Test.cpp:
#include <iostream>
#include "Test.h"
void Test::display() {
std::cout << x;
}
void Test::setVal(int val) {
TestHelper testH;
testH.setX(shared_from_this(), 324);
}
TestHelper.h:
#ifndef TESTHELPER_H
#define TESTHELPER_H
class Test;
class TestHelper
{
public:
void setX(std::shared_ptr<Test> test, int val);
};
#endif
TestHelper.cpp:
#include <memory>
#include "TestHelper.h"
#include "Test.h"
void TestHelper::setX(std::shared_ptr<Test> test, int val) {
/** some algorithm here and then change val to something else */
test->x = val*100;
}
main.cpp:
#include <iostream>
#include <memory>
#include "Test.h"
int main(void){
std::cout << "Hello World!\n";
auto x = std::make_shared<Test>();
x->setVal(130);
x->display();
}
You can run it here: https://paiza.io/projects/e/79dehCx0RRAG4so-sVZcQw
I don't understand why you want this, here's a few variants that compile
reference
// Reference variant
#include <iostream>
class Test;
class TestHelper
{
public:
void setX(Test & test, int val);
};
class Test
{
friend class TestHelper;
int x;
public:
void display() {
std::cout << x;
}
void setVal(int val) {
TestHelper testH;
testH.setX(*this, 324);
}
};
void TestHelper::setX(Test &test, int val)
{
/** some algorithm here and then change val to something else */
test.x = val*100;
}
int main()
{
Test x;
x.setVal(130);
x.display();
}
http://cpp.sh/7t3ec
shared ptr
// Shared ptr variant
#include <iostream>
#include <memory> // Required for shared_ptrs
class Test;
class TestHelper
{
public:
void setX(std::shared_ptr<Test> test, int val);
};
class Test : public std::enable_shared_from_this<Test>
{
friend class TestHelper;
int x;
public:
void display() {
std::cout << x;
}
void setVal(int val) {
TestHelper testH;
testH.setX(shared_from_this(), 324);
}
};
void TestHelper::setX(std::shared_ptr<Test> test, int val)
{
/** some algorithm here and then change val to something else */
test->x = val*100;
}
int main()
{
auto x = std::make_shared<Test>(); // x needs to be created as shared_ptr or it won't work
x->setVal(130);
x->display();
}
http://cpp.sh/87ao2
Perhaps with these you can refine your question?

error: base operand of '->' has non-pointer type

This is my enum header file
//use like PostionType::President
enum PositionType
{ President,
VicePresident,
Secretary,
Treasurer,
Normal
};
And in my Ballot paper header and cpp file
#include <list>
#include <iostream>
#include "Candidate.h"
#include "PositionType.h" //include enum
class BallotPaper
{
private:
PositionType _positionbp;
std::list<Candidate> _candidatesbp;
public:
BallotPaper();
void setPositionBP(PositionType positionbp);
PositionType getPositionBP();
void setCandidateBP(std::list<Candidate> candidatesbp);
std::list<Candidate> getCandidateBP();
Candidate getCandidate(int index);
void ShowCandidates();
~BallotPaper();
};
#include "BallotPaper.h"
#include <string>
#include <iostream>
void BallotPaper::setPositionBP(PositionType positionbp)
{
_positionbp = positionbp;
}
PositionType BallotPaper::getPositionBP()
{
return _positionbp;
}
void BallotPaper::setCandidateBP(std::list<Candidate> candidatesbp)
{
_candidatesbp = candidatesbp;
}
std::list<Candidate> BallotPaper::getCandidateBP()
{
return _candidatesbp;
}
void BallotPaper::ShowCandidates()
{
for(Candidate c : _candidatesbp)
{
c->IncreaseVoteCount(); //ERROR!!!!
}
}
and this will be my candidate header and cpp file
class Candidate:public Member
{
private:
int _votecount;
PositionType _position;
public:
Candidate(std::string name, int id, std::string course, int contact, std::string joindate, PositionType currentposition) ;
~Candidate();
void setVoteCount(int votecount);
int getVoteCount();
void setPosition(PositionType position);
PositionType getPosition();
void IncreaseVoteCount(); //increase _votecount
};
#include "Candidate.h"
Candidate::Candidate()
{
_votecount = 0;
}
void Candidate::setVoteCount(int votecount)
{
_votecount = votecount;
}
int Candidate::getVoteCount()
{
return _votecount;
}
void Candidate::setPosition(PositionType position)
{
_position = position;
}
PositionType Candidate::getPosition()
{
return _position;
}
void Candidate::IncreaseVoteCount()
{
_votecount++;
}
I know is a super long code, and I appreciate for your patience in looking through it. My error is that it seems that it cannot recognize the function of "IncreaseVoteCount" in 'Candidate c'.
I have try to double check the syntax and the code for multiple times but i still don't understand what is the error here.

C++ undefined symbol: NullPointerException error returned from a shared library

I'm having some problems with my code. A shared library is causing an undefined symbol error that I just cannot figure out. All of the files are in the correct locations and the shared library builds successfully but upon executing the program it returns the bellow message.
The error message:
libsp.so: undefined symbol: _ZTIN4Poco20NullPointerExceptionE
From what I can see the problem is the Poco headers I use. The headers I got from an outside source and they should all work, I believe the error is caused by how I call these headers, but I might be wrong.
Bellow is the only code that uses Poco in the libsp library. And the code of the 4 header files I use. I've checked and rechecked and cannot find any issues but am still getting the undefined symbol exception.
File Spexec.cpp (libsp):
#include "../poco/Poco/Base64Encoder.h"
#include "../poco/Poco/DigestEngine.h"
#include "../poco/Poco/MD5Engine.h"
#include "../poco/Poco/Path.h"
using namespace std;
stringstream s_base;
Poco::Base64Encoder encoder(s_base);
Poco::Path path(data.name);
data.path = data.name.substr(0, data.name.length() - path.getFileName().length());
Poco::MD5Engine md5;
stringstream ss;
ss << data.created << data.name;
md5.update(ss.str());
data.name = Poco::DigestEngine::digestToHex(md5.digest());
}
File Base64Encoder.h:
#ifndef Foundation_Base64Encoder_INCLUDED
#define Foundation_Base64Encoder_INCLUDED
#include "Foundation.h"
#include <ostream>
namespace Poco {
class Foundation_API Base64Encoder:, public std::ostream
{
public:
Base64Encoder(std::ostream& ostr);
~Base64Encoder();
private:
Base64Encoder(const Base64Encoder&);
Base64Encoder& operator = (const Base64Encoder&);
};
} // namespace Poco
#endif // Foundation_Base64Encoder_INCLUDED
File DigestEngine.h:
#ifndef Foundation_DigestEngine_INCLUDED
#define Foundation_DigestEngine_INCLUDED
#include "Foundation.h"
#include <vector>
namespace Poco {
class Foundation_API DigestEngine
{
public:
typedef std::vector<unsigned char> Digest;
DigestEngine();
virtual ~DigestEngine();
void update(const void* data, std::size_t length);
void update(char data);
void update(const std::string& data);
virtual std::size_t digestLength() const = 0;
virtual void reset() = 0;
virtual const Digest& digest() = 0;
static std::string digestToHex(const Digest& bytes);
static Digest digestFromHex(const std::string& digest);
presentation
protected:
virtual void updateImpl(const void* data, std::size_t length) = 0;
private:
DigestEngine(const DigestEngine&);
DigestEngine& operator = (const DigestEngine&);
};
File MD5Engine.h:
#ifndef Foundation_MD5Engine_INCLUDED
#define Foundation_MD5Engine_INCLUDED
#include "Foundation.h"
#include "DigestEngine.h"
namespace Poco {
class Foundation_API MD5Engine: public DigestEngine
{
public:
enum
{
BLOCK_SIZE = 64,
DIGEST_SIZE = 16
};
MD5Engine();
~MD5Engine();
std::size_t digestLength() const;
void reset();
const DigestEngine::Digest& digest();
protected:
void updateImpl(const void* data, std::size_t length);
private:
static void transform(UInt32 state[4], const unsigned char block[64]);
static void encode(unsigned char* output, const UInt32* input, std::size_t len);
static void decode(UInt32* output, const unsigned char* input, std::size_t len);
struct Context
{
UInt32 state[4]; // state (ABCD)
UInt32 count[2]; // number of bits, modulo 2^64 (lsb first)
unsigned char buffer[64]; // input buffer
};
Context _context;
DigestEngine::Digest _digest;
MD5Engine(const MD5Engine&);
MD5Engine& operator = (const MD5Engine&);
};
}
File Path.h:
#ifndef Foundation_Path_INCLUDED
#define Foundation_Path_INCLUDED
#include "Foundation.h"
#include <vector>
namespace Poco {
class Foundation_API Path
{
public:
enum Style
{
PATH_UNIX, /// Unix-style path
PATH_WINDOWS, /// Windows-style path
PATH_VMS, /// VMS-style path
PATH_NATIVE, /// The current platform's native style
PATH_GUESS /// Guess the style by examining the path
};
typedef std::vector<std::string> StringVec;
Path();
Path(const char* path);
Path(const std::string& path);
protected:
void parseUnix(const std::string& path);
void parseWindows(const std::string& path);
void parseVMS(const std::string& path);
void parseGuess(const std::string& path);
std::string buildUnix() const;
std::string buildWindows() const;
std::string buildVMS() const;
private:
std::string _node;
std::string _device;
std::string _name;
std::string _version;
StringVec _dirs;
bool _absolute;
};

how can I use constructors in place of setter member functions

my program basically depends on setters to initialize the data in my object instances but I want to remove them and have constructors in place of the setters, Is there a way I can do this or can anybody provide me a reference?
Instantiate object
//Using SDL and standard IO
#include <SDL.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <iomanip>
#include <archer.hpp>
#include <ctime>
#include <ArmouredArcher.hpp>
#include <RNGI.hpp>
using namespace std; //Declaring use of namespace std
void instantiateMuskateer();
int main(int argc, char* argv[])
{
//init muskateer object
instantiateMuskateer();
system("pause");
return 0;
}
Instantiation, Activity and destruction
void instantiateMuskateer()
{
Archer* Muskateer = new Archer();
Muskateer->setName("Brett");
delete Muskateer;
}
.hpp file
#ifndef _Archer_
#define _Archer_
#include <string>
class Archer
{
public:
inline Archer() :
name(""),
healthpoints(0),
baseDamage(0),
range(0)
{ ; } //All Member varials are in a known state
inline Archer(std::string name, int healthpoints, int baseDamage, int range) :
name(name),
healthpoints(healthpoints),
baseDamage(baseDamage),
range(range) //All member variables are in a known state
{
;
}
inline ~Archer() { ; } // empty destructor
inline std::string getName() { return name; }
inline void setName(std::string name) { this->name = name; }
inline int getHealthPoints() { return healthpoints; }
inline void setHealthPoints(int healthpoints) { this->healthpoints = healthpoints; }
inline int getBaseDamage() { return baseDamage; }
inline void setBaseDamage(int baseDamage) { this->baseDamage = baseDamage; }
inline int getRange() { return range; }
inline void setRange(int range) { this->range = range; }
/*std::string getName(); //getter for name
void setName(std::string name); //Set the name
int getHealthPoints();
void setHealthPoints(int healthpoints);
int getBaseDamage();
void setBaseDamage(int baseDamage);
int getRange();
void setRange(int range); */
protected:
private:
// copy constructor
Archer(const Archer& other) = delete;
// overload assignment operator
Archer& operator=(const Archer& other) = delete;
std::string name;
int healthpoints;
int baseDamage;
int range;
};
#endif
In your example, it is really simple, you just have to take the parameters you need in your constructor:
Archer(std::string n) :
name(n),
healthpoints(0),
baseDamage(0),
range(0)
{} //All Member varials are in a known state
And then you can simply do that:
void instantiateMuskateer()
{
Archer* Muskateer = new Archer("Brett");
delete Muskateer;
}
A few comments not related, but to improve your code. Writing inline is useless when you declare and implement your functions inside your class, the inline is implied. Also, if your destructor does nothing, you should not define it or use = default, that way you can enable some optimizations from the compiler.
Also, in your previous function i see no need to allocate the object on the heap, it is again a loss of performance and a source of error (such as forgetting to delete the object), allocate it on the stack:
void instantiateMuskateer()
{
Archer Muskateer("Brett");
// do your things
}
Or use a unique_ptr.

include graphic interface on program

Like title say, I think i have a problem on one of my include.
I'm studient, my teacher gave me a solution to create a visual interface (coded by himself) named EZ-Draw.
But somewhere in my code there is a problem 'cause my compiler tell me many errors of this style:
|364|undefined reference to `CreateCompatibleDC#4'|
|559|undefined reference to `SelectObject#8'|
...
my code:
interpreteur.hpp
#ifndef INTERPRETEUR_HPP_INCLUDED
#define INTERPRETEUR_HPP_INCLUDED
#include <sstream>
#include <map>
#include <math.h>
#include "Pile_Template.hpp"
#include "ez-draw++.h"
#define PI 3.14159265
class Interpreteur {
private:
void (Interpreteur::*ptr)();
EZWindow myWindow;
Pile<double> pile;
Pile<string> pilestr;
bool run;
public:
map<string,void(Interpreteur::*)()> myMap;
Interpreteur();
~Interpreteur();
inline bool getRun() {return run;};
inline void setEmpilerPile(double nombre) {pile.empiler(nombre);};
template <typename T>
string itos(T nombre) // convertit un double en string
{
ostringstream ss;
ss<<nombre;
return ss.str();
}
void addition();
void moins();
void multiplie();
void divise();
void quit();
void push();
void pushstr();
void pop();
void popstr();
void copy();
void copystr();
void print();
void printstr();
void display();
void displaystr();
void count();
void countstr();
void swap();
void swapstr();
void sinus();
void cosinus();
void tangente();
void racine();
void trunc();
void line();
void color();
void drawstr();
void triangle();
void rectangle();
void circle();
};
#endif // SOUS_PROGRAMMES_HPP_INCLUDED
interpreteur.cpp
#include "interpreteur.hpp"
#include <sstream>
#include <map>
#include <math.h>
#include <string>
using namespace std;
void Interpreteur::addition()
{
pile.empiler(pile.depiler()+pile.depiler());
}
void Interpreteur::moins()
{
double nombre=pile.depiler();
nombre=pile.depiler()-nombre;
pile.empiler(nombre);
}
void Interpreteur::multiplie()
{
pile.empiler(pile.depiler()*pile.depiler());
}
void Interpreteur::divise()
{
double nombre=pile.depiler();
nombre=pile.depiler()/nombre;
pile.empiler(nombre);
}
void Interpreteur::quit()
{
run=false;
}
void Interpreteur::push()
{
double i;
cin>>i;
pile.empiler(i);
}
void Interpreteur::pushstr()
{
string chaine;
char merde;
cin>>merde;
if(merde=='"')
{
getline(cin,chaine,'"');
pilestr.empiler(chaine);
}
else
{
cin.putback(merde);
cerr<<"mauvaise chaine de caractères"<<endl;
}
}
void Interpreteur::pop()
{
pile.depiler();
}
void Interpreteur::popstr()
{
pilestr.depiler();
}
void Interpreteur::copy()
{
int i=pile.depiler();
pile.empiler(pile[pile.getSommet()-i]);
}
void Interpreteur::copystr()
{
int i=pile.depiler();
pilestr.empiler(pilestr[pile.getSommet()-i]);
}
void Interpreteur::print()
{
cout<<pile.depiler()<<endl;
}
void Interpreteur::printstr()
{
cout<<pilestr.depiler()<<endl;
}
void Interpreteur::display()
{
pile.afficher(cout);
}
void Interpreteur::displaystr()
{
pilestr.afficher(cout);
}
void Interpreteur::count()
{
pile.empiler(pile.getSommet());
}
void Interpreteur::countstr()
{
pilestr.empiler(itos(pilestr.getSommet()));
}
void Interpreteur::swap()
{
double first=pile.depiler();
double second=pile.depiler();
pile.empiler(first);
pile.empiler(second);
}
void Interpreteur::swapstr()
{
string first=pilestr.depiler();
string second=pilestr.depiler();
pilestr.empiler(first);
pilestr.empiler(second);
}
void Interpreteur::sinus()
{
pile.empiler(sin(pile.depiler()*PI/180));
}
void Interpreteur::cosinus()
{
pile.empiler(cos(pile.depiler()*PI/180));
}
void Interpreteur::tangente()
{
pile.empiler(tan(pile.depiler()*PI/180));
}
void Interpreteur::racine()
{
pile.empiler(sqrt(pile.depiler()));
}
void Interpreteur::trunc()
{
int x=pile.depiler();
pile.empiler(x);
}
void Interpreteur::line()
{
int y2=pile.depiler();
int x2=pile.depiler();
int y1=pile.depiler();
int x1=pile.depiler();
myWindow.drawLine(x1,y1,x2,y2);
}
void Interpreteur::color()
{
int couleur=pile.depiler();
switch(couleur)
{
case 1:{myWindow.setColor(ez_black);break;}
case 2:{myWindow.setColor(ez_red);break;}
case 3:{myWindow.setColor(ez_green);break;}
case 4:{myWindow.setColor(ez_blue);break;}
case 5:{myWindow.setColor(ez_cyan);break;}
case 6:{myWindow.setColor(ez_magenta);break;}
case 7:{myWindow.setColor(ez_yellow);break;}
//pourquoi que on a pas fait le gris ? ez_grey
default:{pile.empiler(couleur); cerr<<"couleur inconnue"<<endl; break;}
}
// COULEUR : ez_black, ez_white, ez_grey, ez_red, ez_green, ez_blue,ez_yellow, ez_cyan, ez_magenta
}
void Interpreteur::drawstr()
{
string str=pilestr.depiler();
int y1=pile.depiler();
int x1=pile.depiler();
myWindow.drawText(EZ_MC,x1,y1,str);
}
void Interpreteur::triangle()
{
int y3=pile.depiler();
int x3=pile.depiler();
int y2=pile.depiler();
int x2=pile.depiler();
int y1=pile.depiler();
int x1=pile.depiler();
myWindow.drawTriangle(x1,y1,x2,y2,x3,y3);
}
void Interpreteur::rectangle()
{
int y2=pile.depiler();
int x2=pile.depiler();
int y1=pile.depiler();
int x1=pile.depiler();
myWindow.drawRectangle(x1,y1,x2,y2);
}
void Interpreteur::circle()
{
int y2=pile.depiler();
int x2=pile.depiler();
int y1=pile.depiler();
int x1=pile.depiler();
myWindow.drawCircle(x1,y1,x2,y2);
}
Interpreteur::Interpreteur()
{
run=true;
myMap["+"]=&Interpreteur::addition;
myMap["-"]=&Interpreteur::moins;
myMap["*"]=&Interpreteur::multiplie;
myMap["/"]=&Interpreteur::divise;
myMap["exit"]=&Interpreteur::quit;
myMap["push"]=&Interpreteur::push;
myMap["pushstr"]=&Interpreteur::pushstr;
myMap["pop"]=&Interpreteur::pop;
myMap["popstr"]=&Interpreteur::popstr;
myMap["copy"]=&Interpreteur::copy;
myMap["copystr"]=&Interpreteur::copystr;
myMap["print"]=&Interpreteur::print;
myMap["printstr"]=&Interpreteur::printstr;
myMap["display"]=&Interpreteur::display;
myMap["displaystr"]=&Interpreteur::displaystr;
myMap["count"]=&Interpreteur::count;
myMap["countstr"]=&Interpreteur::countstr;
myMap["swap"]=&Interpreteur::swap;
myMap["swapstr"]=&Interpreteur::swapstr;
myMap["sin"]=&Interpreteur::sinus;
myMap["cos"]=&Interpreteur::cosinus;
myMap["tan"]=&Interpreteur::tangente;
myMap["sqrt"]=&Interpreteur::racine;
myMap["trunc"]=&Interpreteur::trunc;
myMap["line"]=&Interpreteur::line;
myMap["color"]=&Interpreteur::color;
myMap["drawstr"]=&Interpreteur::drawstr;
myMap["triangle"]=&Interpreteur::triangle;
myMap["rectangle"]=&Interpreteur::rectangle;
myMap["circle"]=&Interpreteur::circle;
}
Interpreteur::~Interpreteur()
{
map<string, void (Interpreteur::*)()>::iterator it;
myMap.erase(it);
}
and here the "EZ-Draw documentation" gived by my teacher to understand ez-draw and ez-draw++
I don't understand what the compiler is trying to tell me
You are using C functions from C++, for this to work you need to explicitly tell the compiler those are C functions. The C header file you are using from C++ should contain those lines to be usable in C++:
#ifdef __cplusplus
extern "C" {
#endif
//The header file which declares the functions which are not linked correctly here
#ifdef __cplusplus
}
#endif
A bit of explanation:
The function "name mangling" is different for C and C++, since in C++ you can overload a function the name of the function alone does not identify a function uniquely, so the compiler adds some symbols to the names of functions in background when you compile to make those names unique (that's the DC#4 in CreateCompatibleDC#4).
Since your linker expects C++ functions, it searches for CreateCompatibleDC#4, but some of your files get compiled in C, and export a function named CreateCompatible, that's why you get a "undefined reference": the linker is telling you it can not find the definition of some functions.