C++ Class inheritance in different files - c++

I'm trying to learn Inheritance mechanism in C++, I have made a Bancnote(Bills) class, and I want to make a class Card inheriting all the functions and variables from Class Bancnote.
And I get this type of error :
include\Card.h|6|error: expected class-name before '{' token|
BANCNOTE.H
#ifndef BANCNOTE_H
#define BANCNOTE_H
#include <iostream>
#include "Card.h"
using namespace std;
class Bancnote
{
public:
Bancnote();
Bancnote(string, int ,int ,int );
~Bancnote( );
int getsumacash( );
void setsumacash( int );
int getsumaplata( );
void setsumaplata( int );
int getrest( );
void setrest( int );
string getnume( );
void setnume( string );
void ToString();
protected:
private:
string nume;
int sumacash;
int rest;
static int sumaplata;
};
#endif // BANCNOTE_H
BANCNOTE.CPP
#include <iostream>
#include "Bancnote.h"
#include "Card.h"
using namespace std;
int Bancnote::sumaplata=0;
Bancnote::Bancnote(string _nume,int _sumacash,int _rest, int _sumaplata )
{
this->nume=_nume;
this->sumacash=_sumacash;
this->rest=_rest;
this->sumaplata=_sumaplata;
}
Bancnote::Bancnote()
{
this->nume="";
this->sumacash=0;
this->rest=0;
this->sumaplata=0;
}
Bancnote::~Bancnote()
{
cout<<"Obiectul"<<"->" <<this->nume<<"<-"<<"a fost sters cu succes";
}
string Bancnote::getnume()
{
return nume;
}
void Bancnote::setnume(string _nume)
{
this->nume=_nume;
}
int Bancnote::getsumacash()
{
return sumacash;
}
void Bancnote::setsumacash(int _sumacash)
{
this->sumacash=_sumacash;
}
int Bancnote::getsumaplata()
{
return sumaplata;
}
void Bancnote::setsumaplata(int _sumaplata)
{
this->sumaplata=_sumaplata;
}
int Bancnote::getrest()
{
return rest;
}
void Bancnote::setrest(int _rest)
{
this->rest=_rest;
}
void Bancnote::ToString()
{
cout<< "-----"<<getnume()<< "-----"<<endl;
cout<<"Suma Cash: "<<this->getsumacash()<<endl;
cout<<"Suma spre plata: "<<this->getsumaplata()<<endl;
cout<<"Restul:"<<this->getrest()<<endl;
}
CARD.H
#ifndef CARD_H
#define CARD_H
#include "Bancnote.h"
class Card: public Bancnote
{
public:
Card();
virtual ~Card();
protected:
private:
};
#endif // CARD_H

You have messed up the includes. What you have is more or less this:
Bancnote.h:
#ifndef BANCNOTE_H
#define BANCNOTE_H
#include "Card.h" // remove this
struct Bancnote {};
#endif
Card.h
#ifndef CARD_H
#define CARD_H
#include "Bancnote.h"
struct Card : Bancnote {}; // Bancnote is not yet declared
// when compiler reaches here
#endif
When in main you include Bancnote.h then this header includes Card.h so you try to declare Card before Bancnote is declared. Actually Bancnote does not need the definition of Card, so simply removing the include should fix it.
PS: there are other issues (see comments below your question). Most importantly it is not clear why a Card is a Bancnote. Second, never put a using namespace std; inside a header! (see here why)

Related

extern vector created in constructor

I have a class Team and a class Ball and I create a vector in constructor of Team that is filled with objects of another class called Player. So I want to use this vector in the class Ball but even though I define it as extern (public) compiler keeps telling me that I have undefined reference to team that is my vector. Here follows the code of Team.cpp and Ball.cpp
Team.h
#define TEAM_H
#include <iostream>
#include <vector>
#include "Player.h"
using namespace std;
extern vector<Player> team;
class Team {
public:
Team();
void fillTeamVector(vector<Player>&);
private:
string teamName;
int faults;
int passes;
int goals;
};
#endif // TEAM_H
Team.cpp
#include "Team.h"
#include <vector>
#include <iostream>
#include "Player.h"
#include "Attacker.h"
#include "Defender.h"
#include "Ball.h"
Team::Team()
{
extern vector<Player> team;
fillTeamVector(team);
}
void Team::fillTeamVector(vector<Player>& team){
// do stuff and store them on vector team
}
And here follows the code for Ball.h note that I commented all the methods that don't affect the problem.
#ifndef BALL_H
#define BALL_H
#include "Player.h"
class Ball
{
public:
Ball();
Player* current;
Player* previous;
/*void setX_ball(int);
int getX_ball() const;
void setY_ball(int);
int getY_ball() const;*/
void assign();
//void changeCurrentToPrevious();
//void changeNextToCurrent(Player*);
private:
int X_ball;
int Y_ball;
};
#endif // BALL_H
Here is the code for Ball.cpp note that in method assign if I create a new (and obviously different vector of Player named team it will compile correctly)
#include "Ball.h"
#include "Team.h"
#include "Player.h"
extern vector<Player> team;
Ball::Ball()
: X_ball(2),
Y_ball(5)
{
current = NULL;
previous = NULL;
}
void Ball::assign(){
//vector<Player> team;
int x;
int y;
x=(team[0].getX())-X_ball;
y=(team[0].getY())-Y_ball;
int min=x+y;
int k=0;
for (int i=1; i<team.size(); i++){
x=(team[i].getX())-X_ball;
y=(team[i].getY())-Y_ball;
int sum=x+y;
if(sum<min){
k=i;
}
}
current = &team[k];
}
By doing
extern vector<Player> team;
you only declare the variable.
In one source file you must actually define the variable:
vector<Player> team;
Note the lack of extern in the definition.
Also note that this has to be done in the global scope, since you want a global variable. So it has to be defined outside of any functions or classes or namespaces.

Debugging C++ compiler error

I'm still a noobie in c++ so I am not to skilled in debugging yet. Just trying to figure out how to fix this compilation error.
CruiseShip.cpp:11: error: expected ā€˜)ā€™ before ā€˜nā€™
CruiseShip.cpp
#include "CruiseShip.h"
#include "Ship.h"
#include <iostream>
using namespace std;
Ship s;
int passengers;
CruiseShip(string n, string y, int p) : Ship(n,y)
{
passengers=p;
}
void print()
{
cout<<"Name: "<<s.getName()<<"\nMaximum passengers:"<<passengers<<endl;
cout<<"-------------------------"<<endl;
}
CruiseShip.h
#ifndef CRUISESHIP_H
#define CRUISESHIP_H
#include "Ship.h"
#include <string>
using namespace std;
//class Ship;
class CruiseShip:public Ship{
private:
int passengers;
Ship::Ship s;
public:
CruiseShip(string, string, int);
virtual void print();
};
#endif
Ship.h
#ifndef SHIP_H
#define SHIP_H
#include <string>
using namespace std;
class Ship{
private:
string name;
string built;
public:
Ship();
Ship(string, string);
string getName();
string getBuilt();
virtual void print();
};
#endif
You have 3 errors:
1 and 2. You don't declare print and CruiseShip (The constructor) as part of the class CruiseShip when you define them. You need to:
CruiseShip::CruiseShip(string n, string y, int p) : Ship(n,y) {
virtual void CruiseShip::print() {
3, you dont have a namespace Ship so this is unnecessary:
Ship::Ship s; // This only needs to be Ship s <- NameSpace::ObjectType nameOfObject;
After this it will compile http://ideone.com/wJ6mPO. It will not link however, because you have undefined references to all of the functions you have yet to define.

c++ Inheritance in different files error

For some reason I can't manage to figure out what is wrong with my inheritance in c++ within different files. The biggest error I get is 'no matching function for call to 'Enemy::Enemy (int&)'
Here is my Monster.cpp code
#include "Monster.h"
#include "Enemy.h"
#include <iostream>
Monster::Monster(int MonsterHealth,int MonsterMana,int Monstersize) // implementation
: Health(MonsterHealth), Mana(MonsterMana), Enemy(Monstersize)
{}
int Monster::dropxp(int enemydropxp){
}
Here is my Monster.h
#ifndef MONSTER_H
#define MONSTER_H
#include "Enemy.h"
class Monster : public Enemy
{
Monster();
Monster(int MonsterHealth, int MonsterMana,int Monstersize);
void TheenemyHealth()
{
int Enemyhealth = 100;
}
int EnemyDamage(int EnemyAttack){
int Attack = EnemyAttack;
Attack = 5;
}
int dropxp(int enemyxpdrop);
private:
int Health = 0;
int Mana = 0;
};
#endif // MONSTER_H
Here is my enemy.cpp
#include "Enemy.h"
Enemy::Enemy(int EnemyHealth,int EnemyMana)
{
Attackpower;
Strenght;
Enemyxp;
}
Enemy::~Enemy()
{
//dtor
}
and my enemy.h
#ifndef ENEMY_H
#define ENEMY_H
class Enemy
{
public:
Enemy(int EnemyHealth,int EnemyMana);
~Enemy();
virtual void TheenemyHealth(){}
virtual int EnemyDamage(int EnemyAttack){
int Attack = EnemyAttack;
}
virtual int dropxp(int enemyxpdrop);
private:
int Attackpower= 0;
int Strenght = 0;
int Enemyxp= 0;
};
#endif // ENEMY_H
Your enemy constructor is defined as Enemy(int EnemyHealth,int EnemyMana); but you are calling it with only one parameter in:
Monster::Monster(int MonsterHealth,int MonsterMana,int Monstersize) // implementation
: Health(MonsterHealth), Mana(MonsterMana), Enemy(Monstersize)
{}
Also your Enemy constructor does nothing:
Enemy::Enemy(int EnemyHealth,int EnemyMana)
{
Attackpower; // does nothing
Strenght; // does nothing
Enemyxp; // does nothing
}

How exactly serialization works in C++?

Here are my code files:
main.cpp
#include <iostream>
#include <fstream>
#include "Car.h"
#include "Engine.h"
using namespace std;
int main() {
Car* car = new Car(1984);
/* do something here */
delete car;
return 0;
}
Car.h
#ifndef CAR_H
#define CAR_H
#include <iostream>
using namespace std;
#include "Engine.h"
class Car {
public:
Car(int);
virtual ~Car();
void serialize(ostream& s) {
engine.serialize(s);
s << ' ' << yearModel;
}
void unserialize(istream& s) {
engine.unserialize(s);
s >> yearModel;
}
private:
Engine engine;
int yearModel;
};
#endif /* CAR_H */
Car.cpp
#include "Car.h"
Car::Car(int year) {
yearModel = year;
}
Car::~Car() {
}
Engine.h
#ifndef ENGINE_H
#define ENGINE_H
#include <iostream>
using namespace std;
class Engine {
public:
Engine();
virtual ~Engine();
void serialize(ostream& s) {
s << ' ' << engineType;
}
void unserialize(istream& s) {
s >> engineType;
}
private:
int engineType;
};
#endif /* ENGINE_H */
Engine.cpp
#include "Engine.h"
Engine::Engine() {
engineType = 1;
}
Engine::~Engine() {
}
What I want to do in the main.cpp is to save the created Car object to file.txt and later read it from there. How does that exactly work? For example: how do I call the serialization function in Car class?
I'm sorry if I sound like a noob, but this whole serialization thing is pretty new to me.
Edit: Code compiles now when I added 'void' in front of all serialize- and unserialize-functions.
This has nothing to do with serialization: a function needs a return type, even if it is void. So this is wrong:
serialize(ostream& s) // look, no return type.
You probably need to either return void,
void serialize(ostream& s) { /* code as before */ }
or return the stream by reference to allow for chaining:
ostream& serialize(ostream& s) {
return s << ' ' << engineType;
}

How to forward declare a class which is in a namespace

I am trying to use forward declarations in header files to reduce the number of #include used and hence reduce dependencies when users include my header file.
However, I am unable to forward declare where namespaces are used. See example below.
File a.hpp:
#ifndef __A_HPP__
#define __A_HPP__
namespace ns1 {
class a {
public:
a(const char* const msg);
void talk() const;
private:
const char* const msg_;
};
}
#endif //__A_HPP__
File a.cpp:
#include <iostream>
#include "a.hpp"
using namespace ns1;
a::a(const char* const msg) : msg_(msg) {}
void a::talk() const {
std::cout << msg_ << std::endl;
}
File consumer.hpp:
#ifndef __CONSUMER_HPP__
#define __CONSUMER_HPP__
// How can I forward declare a class which uses a namespace
//doing this below results in error C2653: 'ns1' : is not a class or namespace name
// Works with no namespace or if I use using namespace ns1 in header file
// but I am trying to reduce any dependencies in this header file
class ns1::a;
class consumer
{
public:
consumer(const char* const text) : a_(text) {}
void chat() const;
private:
a& a_;
};
#endif // __CONSUMER_HPP__
Implementation file consumer.cpp:
#include "consumer.hpp"
#include "a.hpp"
consumer::consumer(const char* const text) : a_(text) {}
void consumer::chat() const {
a_.talk();
}
Test file main.cpp:
#include "consumer.hpp"
int main() {
consumer c("My message");
c.chat();
return 0;
}
UPDATE:
Here is my very contrived working code using the answer below.
File a.hpp:
#ifndef A_HPP__
#define A_HPP__
#include <string>
namespace ns1 {
class a {
public:
void set_message(const std::string& msg);
void talk() const;
private:
std::string msg_;
};
} //namespace
#endif //A_HPP__
File a.cpp:
#include <iostream>
#include "a.hpp"
void ns1::a::set_message(const std::string& msg) {
msg_ = msg;
}
void ns1::a::talk() const {
std::cout << msg_ << std::endl;
}
File consumer.hpp:
#ifndef CONSUMER_HPP__
#define CONSUMER_HPP__
namespace ns1
{
class a;
}
class consumer
{
public:
consumer(const char* text);
~consumer();
void chat() const;
private:
ns1::a* a_;
};
#endif // CONSUMER_HPP__
File consumer.cpp:
#include "a.hpp"
#include "consumer.hpp"
consumer::consumer(const char* text) {
a_ = new ns1::a;
a_->set_message(text);
}
consumer::~consumer() {
delete a_;
}
void consumer::chat() const {
a_->talk();
}
File main.cpp:
#include "consumer.hpp"
int main() {
consumer c("My message");
c.chat();
return 0;
}
To forward declare class type a in a namespace ns1:
namespace ns1
{
class a;
}
To forward declare a type in multiple level of namespaces:
namespace ns1
{
namespace ns2
{
//....
namespace nsN
{
class a;
}
//....
}
}
Your are using a a member of consumer which means it needs concrete type, your forward declaration won't work for this case.
For nested namespaces, since C++17, you can do
namespace ns1::ns2::nsN
{
class a;
}
Apart to forward-declare the class from within its namespace (as #billz says), remember to either use (prepend) that namespace when referring to the forward-declared class, or add a using clause:
// B.h
namespace Y { class A; } // full declaration of
// class A elsewhere
namespace X {
using Y::A; // <------------- [!]
class B {
A* a; // Y::A
};
}
Ref: Namespaces and Forward Class Declarations