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.
Related
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.
I have seen usage of #ifdef macros ( example Eigen library ) to manage platform specific, but haven't seen any one use "inline namespace"s to manage platform specific code.
The github repo belows gives specific code and example usage.
https://github.com/dchichkov/curious-namespace-trick/wiki/Curious-Namespace-Trick
I am wondering if it is a viable technique to use or if there are any gotchas that I am not able to see. Below is the code snippet :
#include <stdio.h>
namespace project {
// arm/math.h
namespace arm {
inline void add_() {printf("arm add\n");} // try comment out
}
// math.h
inline void add_() {
//
printf("common add\n");
//
} inline namespace platform {inline void add() {add_();}}
inline void dot_() {
//
add();
//
} inline namespace platform {inline void dot() {dot_();}}
}
int main() {
project::dot();
return 1;
}
Output :
$g++ func.cpp -Dplatform=common ; ./a.out
common add
$ g++ func.cpp -Dplatform=arm ; ./a.out
arm add
There are at least two ways to achieve same results. First one with namespaces. Second one - with static functions in classes.
With namespaces:
#include <stdio.h>
namespace GenericMath
{
void add();
void dot();
}
namespace ArmMath
{
void add();
using GenericMath::dot;
}
namespace GenericMath
{
void add()
{
printf("generic add");
}
void dot()
{
Math::add();
printf("generic dot");
}
}
namespace ArmMath
{
void add()
{
printf("arm add");
}
using GenericMath::dot;
}
int main()
{
Math::dot();
return 1;
}
With classes:
#include <stdio.h>
class GenericMath
{
public:
static void add();
static void dot();
};
class ArmMath : public GenericMath
{
public:
static void add();
};
void GenericMath::add()
{
printf("generic add");
}
void GenericMath::dot()
{
printf("generic dot");
Math::add();
}
void ArmMath::add()
{
printf("arm add");
}
int main()
{
Math::add();
Math::dot();
return 1;
}
IMO inline namespaces make code less readable and too verbose.
Once issue is that unlike #ifdef, the compiler still compiles all the code that isn't for the current platform.
So you can't use it for dealing with platform-specific APIs.
Sorry for the lack of a descriptive title.
I'm getting an error "one or more multiply defined symbols found"; to be more specific, I'm getting 46 of them. One for each function in my header/source files. Using Visual Studios 2013.
Here is the relevant source code:
augments.h
#ifndef AUGMENTS_H_
#define AUGMENTS_H_
namespace Augments {
// only used for pass-ins for constructors
enum class Weapon_Type {
sword
};
enum class Head_Type {
head
};
enum class Body_Type {
body
};
// the player (Monster) has a head, body and weapon
// that augments his abilities. This will mostly
// be the thing that draws to the screen for each
// augmentation, but more importantly it contains
// specific statistics about each one.
// So if there was a body that was able to fly,
// there would be a bool that denotes this ability.
class Head : public Actor {
const Head_Type type;
public:
Head(Head_Type);
void Update(float dt);
};
class Body : public Actor {
const Body_Type type;
public:
Body(Body_Type);
void Update(float dt);
};
class Weapon : public Actor {
const Weapon_Type type;
public:
Weapon(Weapon_Type);
void Update(float dt);
};
}
using AugHead = Augments::Head;
using AugBody = Augments::Body;
using AugWep = Augments::Weapon;
#endif
augments.cpp
#include "stdafx.h"
#include "Angel.h"
#include "Augments.h"
#include "LD33.h"
Augments::Head::Head(Augments::Head_Type x) : type(x) {
switch ( x ) {
case Head_Type::head:
SetSprite("Images\\head.png");
break;
};
};
void Augments::Head::Update(float dt) {
SetPosition(Game::thePlayer->GetPosition().X,
Game::thePlayer->GetPosition().Y-
MathUtil::ScreenToWorld(Vec2i(0,40)).Y);
};
Augments::Body::Body(Augments::Body_Type x) : type(x) {
switch ( x ) {
case Body_Type::body:
SetSprite("Images\\body.png");
break;
};
}
void Augments::Body::Update(float dt) {
SetPosition(Game::thePlayer->GetPosition().X,
Game::thePlayer->GetPosition().Y);
}
Augments::Weapon::Weapon(Augments::Weapon_Type x ) : type(x) {
switch ( x ) {
case Weapon_Type::sword:
SetSprite("Images\\weapon.png");
break;
}
}
void Augments::Weapon::Update(float dt) {
SetPosition(Game::thePlayer->GetPosition().X,
Game::thePlayer->GetPosition().Y-
MathUtil::ScreenToWorld(Vec2i(0,-40)).Y);
}
monster.h
// monster related
#include "Augments.h"
#include "Angel.h"
#ifndef MONSTER_H_
#define MONSTER_H_
namespace Player {
// contains information like health attack etc
// but more important body types
class Monster : public PhysicsActor {
int max_health, curr_health;
int attack_damage;
Augments::Head* frame_head;
Augments::Weapon* frame_weapon;
Augments::Body* frame_body;
public:
void Refresh(float dt);
int R_Max_Health() const;
int R_Curr_Health() const;
int R_Attack_Damage() const;
Augments::Head* R_Frame_Head();
Augments::Weapon* R_Frame_Weapon();
Augments::Body* R_Frame_Body();
void Set_Max_Health(int);
void Set_Curr_Health(int);
void Add_Curr_Health(int);
void Set_Attack_Damage(int);
// will automatically remove old
// actors from the stage and deallocate
void Set_Frame_Head(Augments::Head_Type);
void Set_Frame_Weapon(Augments::Weapon_Type);
void Set_Frame_Body(Augments::Body_Type);
Monster(Augments::Head_Type,
Augments::Weapon_Type,
Augments::Body_Type);
};
};
using PlMonster = Player::Monster;
#endif
monster.cpp
#include "stdafx.h"
#include "Monster.h"
#include "Augments.h"
#include "Angel.h"
void Player::Monster::Refresh(float dt) {
};
int Player::Monster::R_Max_Health() const { return max_health; }
int Player::Monster::R_Curr_Health() const { return curr_health; }
int Player::Monster::R_Attack_Damage() const { return attack_damage; }
Augments::Head* Player::Monster::R_Frame_Head() { return frame_head; }
Augments::Body* Player::Monster::R_Frame_Body() { return frame_body; }
Augments::Weapon* Player::Monster::R_Frame_Weapon() { return frame_weapon; }
void Player::Monster::Set_Max_Health(int x) { max_health = x; }
void Player::Monster::Set_Curr_Health(int x) { curr_health = x; }
void Player::Monster::Add_Curr_Health(int x) { curr_health += x; }
void Player::Monster::Set_Attack_Damage(int x) { attack_damage = x; }
void Player::Monster::Set_Frame_Head(Augments::Head_Type x) {
if ( frame_head != nullptr ) {
frame_head->Destroy();
delete frame_head;
frame_head = nullptr;
}
frame_head = new Augments::Head(x);
theWorld.Add(frame_head);
};
void Player::Monster::Set_Frame_Weapon(Augments::Weapon_Type x) {
if ( frame_weapon != nullptr ) {
theWorld.Remove(frame_weapon);
delete frame_weapon;
frame_weapon = nullptr;
}
frame_weapon = new Augments::Weapon(x);
theWorld.Add(frame_weapon);
};
void Player::Monster::Set_Frame_Body(Augments::Body_Type x) {
if ( frame_body != nullptr ) {
theWorld.Remove(frame_body);
delete frame_body;
frame_body = nullptr;
}
frame_body = new Augments::Body(x);
theWorld.Add(frame_body);
};
Player::Monster::Monster(Augments::Head_Type head,
Augments::Weapon_Type weapon,
Augments::Body_Type body) {
frame_body = nullptr;
frame_head = nullptr;
frame_weapon = nullptr;
Set_Frame_Body(body);
Set_Frame_Head(head);
Set_Frame_Weapon(weapon);
}
source.cpp
#include "stdafx.h"
#include "LD33.h"
#include "Angel.h"
int main ( ) {
Game::Initialize();
theWorld.StartGame();
theWorld.Destroy();
return 0;
}
Errors include things such as:
Error 43 error LNK2005: "public: int __thiscall Player::Monster::R_Attack_Damage(void)const " (?R_Attack_Damage#Monster#Player##QBEHXZ) already defined in Augments.obj C:\Users\The Shire\Desktop\ludum_dare\ludumdare33\Code\ClientGame\source.obj ClientGame
Error 3 error LNK2005: "public: void __thiscall Player::Monster::Set_Frame_Body(enum Augments::Body_Type)" (?Set_Frame_Body#Monster#Player##QAEXW4Body_Type#Augments###Z) already defined in Augments.obj C:\Users\The Shire\Desktop\ludum_dare\ludumdare33\Code\ClientGame\LD33.obj ClientGame
And it pretty much states similar for every single function in Monster.
Sorry for just dumping a ton of code. I've been trying to debug it for awhile but couldn't come up with any reasonable solution. I have the include guards, I don't see any namespace conflicts, and everything that needs to be defined is outside of the header files. I can't find anything in augments.h that would be causing this. I also thought it might be the enums, but replacing them with just int did not work either.
I'm thinking it might be the order of the include files? hmm. Maybe there's somehow multiple source files somewhere but I would have no clue as to how. Any help?
Had included Monster.cpp in another header file on accident! Oops
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;
}
main:
#include <iostream>
#include <string>
#include "serviceChargeChecking.h"
int main()
{
serviceChargeChecking newAccount("Crim", 111222, 50.00, 100, 1.00);
system("PAUSE");
return 0;
}
serviceChargeChecking.h:
#ifndef H_serviceChargeChecking
#define H_serviceChargeChecking
#include "checkingaccount.h"
#include <string>
class serviceChargeChecking: public checkingAccount
{
public:
void setMonthlyFee(double);
void writeCheck(int);
void getMonthlyStatement() const;
serviceChargeChecking(std::string =" ",int = 0, double = 0.00, int= 0, double = 0.00);
private:
double serviceCharge;
};
#endif
serviceChargeChecking.cpp:
#include "serviceChargeChecking.h"
#include <iostream>
using std::string;
void serviceChargeChecking::setMonthlyFee(double fee)
{
serviceCharge=fee;
}
void serviceChargeChecking::getMonthlyStatement() const
{
checkingAccount::getMonthlyStatement();
std::cout<< "Service Charge: " << serviceCharge << std::endl;
}
void serviceChargeChecking::writeCheck(int ammount)
{
if(checkingAccount::getChecks()>0)
{
checkingAccount::setChecks(checkingAccount::getChecks()-ammount);
}
else
{
std::cout<<"No checks available." << std::endl;
}
}
serviceChargeChecking::serviceChargeChecking(string name, int acct, double bal, int numCheck, double sCharge)
{
bankAccount::setAcctOwnersName(name);
bankAccount::setAcctNum(acct);
bankAccount::setBalance(bal);
checkingAccount::setChecks(numCheck);
serviceCharge=sCharge;
}
checkingAccount.h:
#ifndef H_checkingAccount
#define H_checkingAccount
#include "bankAccount.h"
#include <iostream>
class checkingAccount: public bankAccount
{
public:
virtual void writeCheck()=0;
void deposit(double);
void withdraw(double);
void getMonthlyStatement() const;
int getChecks();
void setChecks(int);
private:
int numChecks;
};
#endif
checkingAccount.cpp:
#include "checkingAccount.h"
#include <iostream>
int checkingAccount::getChecks()
{
return numChecks;
}
void checkingAccount::setChecks(int c)
{
numChecks=c;
}
void checkingAccount::deposit(double d)
{
bankAccount::setBalance(bankAccount::getBalance()+d);
}
void checkingAccount::withdraw(double w)
{
bankAccount::setBalance(bankAccount::getBalance()-w);
}
void checkingAccount::getMonthlyStatement() const
{
bankAccount::getMonthlyStatement();
}
bankAccount.h:
#ifndef H_bankAccount
#define H_bankAccount
#include <string>
class bankAccount
{
public:
std::string getAcctOwnersName() const;
int getAcctNum() const;
double getBalance() const;
void getMonthlyStatement() const;
void setAcctOwnersName(std::string);
void setAcctNum(int);
void setBalance(double);
virtual void withdraw(double)=0;
virtual void deposit(double)=0;
private:
std::string acctOwnersName;
int acctNum;
double acctBalance;
};
#endif
bankAccount.cpp:
#include "bankAccount.h"
#include <iostream>
using std::string;
string bankAccount::getAcctOwnersName() const
{
return acctOwnersName;
}
int bankAccount::getAcctNum() const
{
return acctNum;
}
double bankAccount::getBalance() const
{
return acctBalance;
}
void bankAccount::setAcctOwnersName(string name)
{
acctOwnersName=name;
}
void bankAccount::setAcctNum(int num)
{
acctNum=num;
}
void bankAccount::setBalance(double b)
{
acctBalance=b;
}
void bankAccount::getMonthlyStatement() const
{
std::cout << "Name on Account: " << getAcctOwnersName() << std::endl;
std::cout << "Account Id: " << getAcctNum() << std::endl;
std::cout << "Balance: " << getBalance() << std::endl;
}
I know this is a lot of code to go through but can anyone help me understand why i cannot create an object from the class serviceChargeChecking the error is telling me that i cannot create an object from the abstract class but it doesn't seem to be abstract to me.
serviceChargeChecking implements void writeCheck(int), but the pure virtual function from checkingAccount has type void writeCheck(), so it's still pure in serviceChargeChecking, which makes the class abstract.
You have this in the abstract class checkingAccount:
virtual void writeCheck()=0;
but implement this in the derived class serviceChargeChecking:
void writeCheck(int);
The signature must be the same.
The writeCheck() method has different signatures in serviceChargeChecking and checkingAccount.
If you use C++11, use override in order to avoid this kind of error.
It's because your CheckingAcount has writeCheck() and serviceChargeChecking has writeCheck(int);
This probably due to the fact that you failed to Override checkingAccount's, writeCheck method, the abstract prototype was was
in checkingAccount class
virtual void writeCheck()=0;
and in serviceChargeChecking class
void writeCheck(int);
note the parameters, you didn't override checkingAccount's writeCheck you probably inherited it (implicitly), the serviceChargeChecking made a new writeCheck with an int parameter.