You see I've been trying to create a std::vector which contains the Entity class inside the IState class. Both classes are interfaces.
The error is
'Entity' was not declared in this scope
and it points to :
protected:
std::vector <Entity*> ent_map;
inside IState.h
I've been trying for hours now to solve it. Once I made a forward declaration inside IState.h but once I did and tried to use the vector it spews out that it's an incomplete class, so I was back to square one.
Any ideas?
Entity.h
#ifdef __ENTITY__
#define __ENTITY__
#include <iostream>
#include <SDL.h>
class Entity
{
public:
virtual ~Entity();
virtual void load(const char* fileName, std::string id, SDL_Renderer* pRenderer) = 0;
virtual void draw() = 0;
virtual void update() = 0 ;
virtual void clean() = 0;
/*void int getX() { return m_x;}
void int getY() { return m_y;}
void std::string getTexID {return textureID;}
*/
};
#endif // __ENTITY__
IState.h
#ifndef IState_
#define IState_
#include "Entity.h"
#include <vector>
class IState
{
public :
virtual ~IState();
virtual void update() = 0;
virtual void render(SDL_Renderer* renderTarget) = 0;
virtual bool onEnter() = 0;
virtual bool onExit() = 0;
virtual void handleEvents(bool* gameLoop,SDL_Event event) = 0;
virtual void resume() = 0;
virtual std::string getStateID() = 0;
virtual void setStateID(std::string id) = 0;
protected:
std::vector <Entity*> ent_map;
};
#endif // IState_
The content of "Entity.h" won't be included at all.
Change
#ifdef __ENTITY__
to
#ifndef __ENTITY__
BTW: The name contains double underscore or begins with an underscore followed by an uppercase letter is reserved in C++, you need to be careful about it.
Related
I'm trying to practice "Observer Design Pattern". When I thought a abstract's pure virtual method has been override by it's derived class, a error occurred.
There is a observer which is an abstract class in a independent file:
#ifndef DESIGN_PATTERNS_OBSERVER_H
#define DESIGN_PATTERNS_OBSERVER_H
#include "subject.h"
class Subject;
class Observer{
protected:
Observer();
public:
virtual ~Observer();
virtual void update(Subject *the_changed_subject) = 0;
};
Observer::Observer() {}
Observer::~Observer() {}
#endif //DESIGN_PATTERNS_OBSERVER_H
Observer defined a pure virtual method "update" which overrides as follow:
#ifndef DESIGN_PATTERNS_CONCRETE_OBSERVER_H
#define DESIGN_PATTERNS_CONCRETE_OBSERVER_H
#include <iostream>
#include "observer.h"
#include "concrete_subject.h"
class ConcreteObserver : public Observer{
public:
void update(Subject *the_changed_subject) override {
auto cs = dynamic_cast<ConcreteSubject *>(the_changed_subject);
std::cout << "status changed to " << cs->get_status() << std::endl;
}
};
#endif //DESIGN_PATTERNS_CONCRETE_OBSERVER_H
And also there is a subject which is an abstract class too.The error "pure virtual method called" happened in "notify" method where I had marked.
From debug, it seems "notify" uses Observer's "update" rather than ConcreteObserver's.
However,in main function the _observers should stored pointers of ConcreteObservers which override "update".
#ifndef DESIGN_PATTERNS_SUBJECT_H
#define DESIGN_PATTERNS_SUBJECT_H
#include <list>
#include "observer.h"
class Subject {
private:
std::list<Observer*> *_observers;
protected:
Subject();
public:
virtual ~Subject();
virtual void attach(Observer*);
virtual void detach(Observer*);
virtual void notify();
};
Subject::Subject() {
_observers = new std::list<Observer*>;
}
Subject::~Subject() {
delete _observers;
}
void Subject::attach(Observer *o) {
_observers->push_back(o);
}
void Subject::detach(Observer *o) {
_observers->remove(o);
}
void Subject::notify() {
for (Observer* observer : *_observers) {
//here is where error comes out, found by debug
observer->update(this);
}
}
#endif //DESIGN_PATTERNS_SUBJECT_H
And it has a derived class "ConcreteSubject":
#ifndef DESIGN_PATTERNS_CONCRETE_SUBJECT_H
#define DESIGN_PATTERNS_CONCRETE_SUBJECT_H
#include "subject.h"
class ConcreteSubject : public Subject {
private:
int status;
public:
ConcreteSubject() {
status = 0;
}
void set_status(int s) {
this->status = s;
Subject::notify();
}
int get_status() {
return status;
}
};
#endif //DESIGN_PATTERNS_CONCRETE_SUBJECT_H
The main function:
#include <iostream>
#include <vector>
#include "singleton.h"
#include "observer/concrete_subject.h"
#include "observer/concrete_observer.h"
void test2() {
ConcreteSubject concreteSubject;
std::vector<ConcreteObserver> observers;
for (int i = 0; i < 5; ++i) {
ConcreteObserver observer = ConcreteObserver();
concreteSubject.attach(&observer);
observers.push_back(observer);
}
concreteSubject.set_status(2);
}
int main() {
test2();
return 0;
}
As I mentioned before, the _observers of ConcreteSubject's super class Subject should stored pointers of ConcreteObservers which override "update" already.
I don't understand why Observer's "update" still called.
Here is another strange thing.I make a small test has almost the same relationship of classes I showed.But no error occured.
class ABaseA{
public:
virtual void do_some() = 0;
};
class MidA : public ABaseA{
public:
void do_some() override {
cout << "real do some" << endl;
}
};
class ABaseB{
private:
list<ABaseA*> *bases;
public:
ABaseB() {
bases = new list<ABaseA*>();
}
virtual ~ABaseB() = default;
virtual void add(ABaseA* item) {
bases->push_back(item);
}
virtual void do_active() {
for(ABaseA *p : *bases) {
p->do_some();
}
}
};
class MidB : public ABaseB{
public:
MidB() = default;
void active() {
ABaseB::do_active();
}
};
void test3() {
MidA midA;
MidB midB;
midB.add(&midA);
midB.active();
}
The only difference is this code is in one file.
In the file of Subject.h you should be transfer below code to Subject.cpp:
Subject::Subject() {
_observers = new std::list<Observer*>;
}
Subject::~Subject() {
delete _observers;
}
void Subject::attach(Observer *o) {
_observers->push_back(o);
}
void Subject::detach(Observer *o) {
_observers->remove(o);
}
void Subject::notify() {
for (Observer* observer : *_observers) {
//here is where error comes out, found by debug
observer->update(this);
}
}
Also you should be add class Observer; in top of Subject.h
#include <list>
#include "Observer.h"
class Observer; //you should be add this line
class Subject {
private:
std::list<Observer*> *_observers;
protected:
Subject();
public:
virtual ~Subject();
virtual void attach(Observer*);
virtual void detach(Observer*);
virtual void notify();
};
I have a problem with this code when I tried to create an instance of this class, an error appears to be
not allowed to use the abstracted class "SavingAccount"
I don't know what can I do. I followed the steps given by edx Microsoft Intermediate C++.
BankAccount.h
#pragma once
#include <string>
class BankAccount
{
protected:
double balance;
public:
BankAccount(double initialBanlance);
virtual ~BankAccount();
double getBalance() const;
virtual void deposit(double amount);
virtual void withdraw(double amount);
virtual std::string getTermAndConditions() = 0;
virtual double getGuaranteeLimit() = 0;};
BankAccount.cpp
#include "BankAccount.h"
BankAccount::BankAccount(double initialBanlance)
:balance(initialBanlance)
{}
BankAccount::~BankAccount()
{}
double BankAccount::getBalance() const
{return balance;}
void BankAccount::deposit(double amount)
{
balance += amount;
}
void BankAccount::withdraw(double amount)
{balance -= amount;}
Freezable.h
#pragma once
//Pure virtual class ,representing the "freeable" capability
class Freezable {
public:
virtual void freeze()=0;
virtual void unfreeze()=0;
};
Loggable.h
#pragma once
#include <string>
//Pure virtual class, representing the "loggable"'
class loggable{
public:
virtual void log(const std::string& message)const = 0;};
SavingAccount.h
#pragma once
#include "BankAccount.h"
#include "Freezable.h"
#include "Loggable.h"
#include <list>
class SavingAccount :public BankAccount, public Freezable, public loggable
{
private:
double interestRate;
bool frozen;
public:
SavingAccount(double initialBalance, double interestRate = 0.0);
virtual ~SavingAccount();
void earnInterest();
virtual void deposit(double amount);
virtual void withdraw(double amount);
//implement pure virtual function from BankAccount class.
virtual std::string getTermAndConditions();
virtual double getGuarranteeLimit();
//Implement pure virtual from Freezable
virtual void freeze();
virtual void unfreeze();
//Implement pure virtual from Loggable class
virtual void log(const std::string & message)const;
};
SavingAccount.cpp
#include "SavingAccount.h"
#include <iostream>
SavingAccount::SavingAccount(double initialBalance, double interestRate)
:BankAccount(initialBalance), interestRate(interestRate), frozen(false)
{}
SavingAccount::~SavingAccount() {}
void SavingAccount::earnInterest()
{
if (!frozen) {
double interest = balance * (interestRate / 100);
deposit(interest);
}
}
void SavingAccount::deposit(double amount) {
if (!frozen) {
BankAccount::deposit(amount);
log("Deposit:" + std::to_string(amount));
}
}
void SavingAccount::withdraw(double amount) {
if (!frozen && amount <= balance) {
BankAccount::withdraw(amount);
log("withdrwal:" + std::to_string(amount));
}
}
std::string SavingAccount::getTermAndConditions() {
return "This is a savings account, You cannot go overdrawn.You earn interest.";
}
double SavingAccount::getGuarranteeLimit() { return 1000000; }
void SavingAccount::freeze() { frozen = true; }
void SavingAccount::unfreeze() { frozen = false; }
void SavingAccount::log(const std::string & message) const
{ std::cout << message << std::endl; }
You have a typo. The base class BankAccount is a pure abstract class, which has a virtual member function called
virtual double getGuaranteeLimit() = 0;
^^
and in your SavingAccount class(which is derived) you have implemented
virtual double getGuarranteeLimit();
^^
which is not same as base class. Hence, you never override the function in your derived class.
That is why you need to practice with override specifier which will produce a compiler error if no matching function is found in base class.
See, for example, compiling with Clag 7.0 clearly gives a compiler error:
prog.cc:76:17: error: 'getGuarranteeLimit' marked 'override' but does not override any member functions
virtual double getGuarranteeLimit()override;
I have a noncopyable monster base class, I also have a IView class.
I have a hobgoblin class that inherits from both monster an IView ,
I have a controller that takes a pointer to IView as a parameter.
Basically I want to check if hobgoblin exploded.
I'm using gmock / gtest
I keep getting
Actual function call count doesn't match EXPECT_CALL(h, Explode())...
Expected: to be called at least once
Actual: never called - unsatisfied and active
when i use the mock object. What am i missing?
Monster Base
#ifndef MONSTER_H
#define MONSTER_H
#include <string>
// interface for all monsters
class monster {
public:
virtual ~monster();
// forbid copying
monster(monster const &) = delete;
monster & operator=(monster const &) = delete;
void receive_damage(double damage);
void interact_with_chainsaw();
std::string name() const;
protected:
// allow construction for child classes only
monster();
private:
virtual void do_receive_damage(double damage) = 0;
virtual void do_interact_with_chainsaw() = 0;
virtual std::string do_name() const = 0;
};
#endif // MONSTER_H
IView
#ifndef IVIEW_H
#define IVIEW_H
class IView
{
public:
virtual void Explode() = 0;
virtual ~IView(){}
};
#endif // IVIEW_H
Hobgoblin
#ifndef HOBGOBLIN_H
#define HOBGOBLIN_H
#include "monster.h"
#include "iview.h"
class hobgoblin : public monster, public IView
{
public:
hobgoblin();
void Explode();
virtual ~hobgoblin();
private:
void do_receive_damage(double damage) final;
void do_interact_with_chainsaw() final;
std::string do_name() const final;
double health_;
};
#endif // HOBGOBLIN_H
#include "hobgoblin.h"
#include <QDebug>
hobgoblin::hobgoblin() :
health_(100.0)
{
}
hobgoblin::~hobgoblin()
{
}
void hobgoblin::Explode()
{
health_ = 0;
qDebug() << "Health is 0";
}
void hobgoblin::do_receive_damage(double damage)
{
health_ -= damage;
}
void hobgoblin::do_interact_with_chainsaw()
{
// imagine horrible, gory things here such as
// having to deal with a singleton
}
std::string hobgoblin::do_name() const
{
static std::string const name("Furry hobgoblin of nitwittery +5");
return name;
}
Controller
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include "iview.h"
class Controller
{
public:
Controller(IView *view);
void Explode();
~Controller();
private:
IView *m_View;
};
#endif // CONTROLLER_H
#include "controller.h"
#include <QDebug>
Controller::Controller(IView *view):
m_View(view)
{
}
void Controller::Explode()
{
m_View->Explode();
}
Controller::~Controller()
{
}
Unit Test
class mockmonster : public IView
{
public:
MOCK_METHOD0(Explode,void());
virtual ~mockmonster(){}
};
TEST(MockMonster,Explode)
{
// this is not calling explode as expected.
mockmonster h;
Controller c(&h);
c.Explode();
}
TEST(HobGoblin,Explode)
{
// this calls explode fine
hobgoblin h;
Controller c(&h);
c.Explode();
}
Well, shouldn't your Explode function be virtual?
By the looks of it, your mockmonster is shadowing IView's function. Since Controller is taking a pointer to IView, and Explode is non-virtual, it will invoke IView's version.
As a side-note, I doubt if either of your classes being non-copyable matters here. When using gmock, non-copyable classes are problematic when setting up expectations/assertions (i.e. you expect a function to be called with a specific object - this object would have to be copied internally by gmock, and that might fail).
I have three classes defined in header files:
Organizm.h:
#ifndef Organizm_H
#define Organizm_H
class Organizm {
public:
int sila;
int inicjatywa;
int trup;
virtual void akcja() = 0;
virtual void kolizja() = 0;
virtual void rysowanie() = 0;
};
#endif
Zwierze.h:
#include "config.h"
#include "Organizm.h"
#ifndef Zwierze_H
#define Zwierze_H
class Zwierze : public Organizm {
public:
void akcja(int *, int *);
void kolizja(Organizm *);
};
#endif
And Wilk.h:
#include "Zwierze.h"
#ifndef Wilk_H
#define Wilk_H
class Wilk: public Zwierze {
public:
Wilk();
void rysowanie();
};
#endif
All non virtual methodths are defined in corresponding files: Organizm.cpp, Zwierze.cpp Wilk.cpp
But when compiling I get following error messg:
g++ -c -o main.o main.cpp
main.cpp: In function ‘int main()’:
main.cpp:13:16: error: cannot allocate an object of abstract type ‘Wilk’
w1 = new Wilk();
^
In file included from main.cpp:5:0:
Wilk.h:6:7: note: because the following virtual functions are pure within ‘Wilk’:
class Wilk: public Zwierze {
^
In file included from Swiat.h:2:0,
from main.cpp:3:
Organizm.h:11:16: note: virtual void Organizm::akcja()
virtual void akcja() = 0;
^
Organizm.h:12:16: note: virtual void Organizm::kolizja()
virtual void kolizja() = 0;
^
<wbudowane>: polecenia dla obiektu 'main.o' nie powiodły się
make: *** [main.o] Błąd 1
zsh: exit 2 make
What am I doing wrong and how can I solve that?
void akcja(int *, int *) are different from void akcja() (overloading). You don't define void akcja() anywhere.
In Zwierze You are not overriding the methods from Organizm.
This compiles:
#include <iostream>
using namespace std;
class Organizm {
public:
int sila;
int inicjatywa;
int trup;
virtual void akcja() = 0;
virtual void kolizja() = 0;
virtual void rysowanie() = 0;
};
class Zwierze : public Organizm {
public:
void akcja(){};
void kolizja(){};
};
class Wilk: public Zwierze {
public:
Wilk(){};
void rysowanie(){};
};
int main() {
Wilk wilk;
return 0;
}
In your case already Zwierze has 2 sets of akcja and kolizja declared. One declared AND defined in Organizm and its implementation. The second and were derived from Organizm and NOT overridden due to different signatures. What you did was overloading.
you didnt declare void rysowanie() in any of your class, therefore your Wilk class remains a abstract class. and a abstract class cant be instantiated.
Moreover, you have overloaded the virtual functions void akcja() and void kolizja(), which is again different and dont make your class an non abstract class.
define the below functions in Organizm
virtual void akcja(int *, int *);
virtual void kolizja(Organizm *);
and also give body of void rysowanie()
I have the following class:
#include <string>
#include <stack>
#include <queue>
#include "map.h"
using namespace std;
#ifndef CONTAINER_H_
#define CONTAINER_H_
struct PathContainer {
int x, y;
string path;
};
class Container {
public:
virtual void AddTile(string, FloorTile *) = 0;
virtual void ClearContainer() = 0;
virtual PathContainer *NextTile() = 0;
};
class StackImpl : public Container {
private:
stack<PathContainer> cntr;
public:
StackImpl();
void AddTile(string, NeighborTile *);
void ClearContainer();
PathContainer *NextTile();
};
class QueueImpl : public Container {
private:
queue<PathContainer> cntr;
public:
QueueImpl();
void AddTile(string, NeighborTile *);
void ClearContainer();
PathContainer *NextTile();
};
#endif
When I try creating StackImpl or QueueImpl object like so:
Container *cntr;
cntr = new StackImpl();
or
Container *cntr;
cntr = new QueueImpl();
I get the following error at compile:
escape.cpp: In function ‘int main(int, char**)’:
escape.cpp:26: error: cannot allocate an object of abstract type ‘StackImpl’
container.h:23: note: because the following virtual functions are pure within ‘StackImpl’:
container.h:18: note: virtual void Container::AddTile(std::string, FloorTile*)
Any ideas?
typeid(NeighborTile *) != typeid(FloorTile *). The signatures differ, so they don't count as "the same" method even if NeighborTile inherits from FloorTile.