I want to compile the Rigi source code but I get some error while compiling:
adt/object.h: At global scope:
adt/object.h:35:18: error: ‘class RigiObject RigiObject::RigiObject’ is inaccessible
adt/chararray.h:51:13: error: within this context
make: *** [cl_arcflags.o] Error 1
Here our two files.
object.h:
#ifndef OBJECTH
#define OBJECTH 1
#include <stdio.h>
#ifndef STREAM_H
#include <iostream>
#endif
#ifndef __STRING_H
#include <string.h>
#endif
#ifndef __STDLIB_H
#include <stdlib.h>
#endif
#ifndef _CCHEADER_H_
#include "CCheader.h"
#endif
extern char* indent_line(int);
class RigiObject;
typedef RigiObject* ObjectPtr;
#define Oberr(a) fprintf(stderr,"ERROR :: Generic Object Routine Called :: %s\n","a");
class RigiObject {
public:
RigiObject() {/*Oberr(RigiObject)*/;}
~RigiObject() {/*Oberr(~RigiObject)*/;}
// Routines that are really described by the Derived Classes
virtual int Printout(int) const
{Oberr(printout); return (int) 0;}
virtual unsigned int Hash() const
{Oberr(hash); return (unsigned int) 0; }
virtual RigiBool isEqual(void* a) const
{Oberr(isEqual); a = NIL;
(void) abort();
return (RigiBool) RigiFalse;}
virtual void Delete_class(ObjectPtr)
{Oberr(delete_type);}
virtual void* Create_class();
virtual void* Duplicate_class();
};
#endif
and chararray.h:
#ifndef CHARARRAYH
#define CHARARRAYH
#ifndef ARRAYOBIDH
#include "array.h"
#endif
#ifndef CHARTYPEH
#include "chartype.h"
#endif
class CharArray;
typedef CharArray* CharArrayPtr;
class CharArray : public Array {
int slot;
public:
// Routines to initialize and destroy the class.
CharArray(unsigned int size = CLTN_DEFAULT_CAPACITY);
CharArray(const CharArray&);
~CharArray();
// Functions that are Required to Use this Class as an Object
// .... all routines the same as in Class Array.......
// Routines that are required by a Collection class and derived classes
// of Collections. [See Array Class for these routines.]
virtual unsigned int size() const {return slot;}
// .... all routines the same as in Class Array.......
// Routines specific to this class
void operator=(const CharArray&);
RigiBool operator==(const CharArray&) const;
void Create(char*);
void Create(char*,int);
void Create(int, char*);
void Add(char*);
void Add(CharType&);
void Addob(RigiObject& ob)
{Array::Add(slot++,&ob);}
void Append(char*);
char* Concat(char);
int FindIndex(char*);
char* Remove()
{return ((CharTypePtr)Array::Remove(--slot))->string();}
ObjectPtr Pop()
{return (Array::Remove(--slot));}
ObjectPtr Look(int i)
{return (Array::At(i));}
void Empty();
virtual unsigned int Size() const
{return slot;}
char* Peek();
char* At(int);
};
#endif
What's wrong with the code?
Assuming that the type RigiBool in the declaration RigiBool operator==(const CharArray&) const; is not defined in one of the headers "array.h" "chartype.h" I think you should include the header containing definition of the type, and just to be sure the "object.h" too.
For cases where a header file uses values of class type variables (not pointers and references) it is recommended to include the headers that contain the class definition. Otherwise a simple forward declaration should be enough.
The types RigiBool, RigiObject and ObjPtr are not available in chararray.h: you need to include object.h (plus whatever else defines RigiBool if CCHeader.h doesn't) -- similarly for RigiBool and RigiFalse in object.h
// somewhere at the top of chararray.h
#include "object.h"
Note: if you define virtual member functions in RigiObject, you should declare the destructor virtual as well
Note: You already have include guards in the #included headers, no need to put them around the #include directives -- doing otherwise indicates (falsely in your case) that you are doing conditional compiling
//chararray.h
#ifndef CHARARRAYH
#define CHARARRAYH
#include "array.h"
#include "chartype.h"
...
//object.h
#ifndef OBJECTH
#define OBJECTH
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include "CCheader.h"
...
It's hard to say from the little information but I would assume RigiBool is a derived class of RigiObject? When you now reference RigiBool in chararray.h it has to know the RigiObject base class but the RigiObject also needs to know about RigiBool. So you can't declare the base class without knowing the derived RigiBool. Try if forward declaring RigiBool in object.h helps to break the cycle.
Related
I would like this mov() virtual member function to get() the coordinates x,y
However there is this error which doesn't make sense at all
pirate.o:: In function 'ZN6Pirate3movEPS_PA100_3Sea':|
pirate.cpp:: undefined reference to `Ship::getX() const' (line 7)
getX() is inherited
Parent Class:Ship, Derived class:Pirate
Ship.h
#ifndef SHIP_H
#define SHIP_H
#include <iostream>
#include "sea.h"
#define SIZE 100
class Ship
{
private:
int x,y; //Coordinates of ship
public:
Ship(){}
virtual void func()=0;
virtual void mov()=0;
protected:
int getX()const;
int getY()const;
};
#endif
Ship.cpp
#include "Ship.h"
int Ship::getX()const
{return x;}
int Ship::getY()const
{return y;}
virtual void func()=0;
virtual void mov()=0;
Pirate.h
#ifndef PIRATE_H
#define PIRATE_H
#include "ship.h"
#include "sea.h"
class Pirate : public Ship
{
protected:
void func();
void mov(Pirate * ship , Sea Map[SIZE][SIZE]);
};
#endif
Pirate.cpp
#include "pirate.h"
void Pirate::func(){}
void Pirate::mov(Pirate* ship , Sea Map[SIZE][SIZE])
{
int x_ref = ship->getX();
int y_ref = ship->getY();
}
Sea.h
#ifndef SEA_H
#define SEA_H
#include "ship.h"
class Sea
{
private:
bool hasShip;
public:
Sea(){hasShip=0;}
bool gethasShip()const{return hasShip;}
void sethasShip(bool i){hasShip = i;}
};
#endif
The other answer is exactly right. If you remove those two lines it will compile correctly, and the error you're getting (and the fact that you're not getting other errors) is due to the fact that Ship.cpp is not properly included in the compilation process.
I'm not sure if you have access to Visual Studio 2013, but if you do, I tested it to be sure with the following solution/project: http://filebin.ca/1i9z9TwF2kf5/Pirates.zip
You forgot to compile and link Ship.cpp
I can tell this because if you'd tried to compile it then you'd have got an error here:
virtual void func()=0;
virtual void mov()=0;
That's not valid C++, you don't define pure virtuals like that (you don't need to define them at all unless they are destructors or you call them explicitly)
If you don't link with the file with the definition of Ship::getX() const then it's not surprising that the linker tells you it's undefined.
just getting an odd error and I'm not entirely sure as to why.
I have 4 files (two headers and two implementations). The issue is inside the headers:
The main file ONLY includes the Station.h, which is why Stations.h is included inside it.
Station.h
#ifndef STATION_H
#define STATION_H
#include "Stations.h"
#include <string>
enum PassType{student, adult};
class Station{
std::string station_name;
unsigned int student_passes;
unsigned int adult_passes;
public:
Station();
void set(const std::string&, unsigned, unsigned);
void update(PassType, int);
unsigned inStock(PassType) const;
const std::string& getName() const;
};
#endif
Stations.h
#ifndef STATIONS_H
#define STATIONS_H
#include "Station.h"
namespace w2{
class Stations{
Station *station;
public:
Stations(char *);
void update() const;
void restock() const;
void report() const;
~Stations();
};
}
#endif
It doesn't know what Station is. I'm getting the following error:
./Stations.h:9:2: error: unknown type name 'Station'; did you mean 'Stations'?
Station *station;
What exactly am I missing here?
You are #includeing Stations.h in Station.h. As a result, the compiler sees class Stations before class Station. In this case, it doesn't appear that Station requires Stations, so you can simply remove the include.
If Station did need to know about Stations, then you'd have to use a forward declaration in one of the headers or the other (and be careful not to use the forward-declared class in a way that required the full definition).
Don't forget to put a semicolon after you declare the Stations class:
class Stations {
Station *station;
};
U need to do the forward declaration.
Remove the #include "Stations.h" from the Station.h
#ifndef STATIONS_H
#define STATIONS_H
#include "Station.h"
namespace w2{
class Station;
class Stations{
Station *station;
public:
Stations(char *);
void update() const;
void restock() const;
void report() const;
~Stations();
};
}
#endif
This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 8 years ago.
I have these two classes that need each other and inherited from the same class. Wehn I compile Seller.h, it compiles fine but when I compile Buyer.h I get errors from Seller.h.
So when i compile Buyer.h I get errors such as :
Seller.h:14:16: error: âBuyerâ has not been declared
void addBuyer(Buyer*);
^
Seller.h:15:14: error: âBuyerâ was not declared in this scope
std::vector<Buyer*> getBuyers() const;
Seller.h:20:17: error: âOrderâ has not been declared
void fillOrder(Order*);
^
They are #included but it still says out of scope.
#ifndef SELLER_H
#define SELLER_H
#include "Entity.h"
#include <string>
#include <vector>
#include "Inventory.h"
#include "Buyer.h"
#include "Order.h"
class Seller : public virtual Entity
{
public:
Seller(const std::string &, const std::string &, double=0.0);
virtual~Seller(){}
void addBuyer(Buyer*);
std::vector<Buyer*> getBuyers() const;
void setInventory(Inventory*);
Inventory* getInventory() const;
virtual void list() const override;
virtual void step() override;
void fillOrder(Order*);
private:
Inventory* inv;
std::vector <Buyer*> buyers;
};
#endif
Buyer.h
#ifndef BUYER_H
#define BUYER_H
#include <string>
#include "Entity.h"
#include <queue>
#include "Order.h"
#include "Seller.h"
class Buyer : public virtual Entity
{
public:
Buyer(const std::string &, const std::string &, double =0.0 );
virtual ~Buyer(){}
void addSeller(Seller *);
std::queue <Seller *> getSellers() const;
void addOrder(Order *);
std::queue <Order*> getOrders() const;
virtual void list() const override;
virtual void step() override;
private:
std::queue <Order*> orders;
std::queue <Seller*> sellers;
};
#endif
You have a cyclic dependency between Seller and Buyer. This will never work because the compiler requires the declaration of Seller in order to compile Buyer... yet it also requires the declaration of Buyer to compile Seller.
You can instead forward declare your classes because all you actually use are pointers to these types. For example:
#ifndef SELLER_H
#define SELLER_H
#include "Entity.h"
#include <string>
#include <vector>
#include "Inventory.h"
#include "Order.h"
// forward declaration of Buyer
class Buyer;
class Seller : public virtual Entity
{
public:
Seller(const std::string &, const std::string &, double=0.0);
virtual ~Seller(){}
void addBuyer(Buyer*);
std::vector<Buyer*> getBuyers() const;
void setInventory(Inventory*);
Inventory* getInventory() const;
virtual void list() const override;
virtual void step() override;
void fillOrder(Order*);
private:
Inventory* inv;
std::vector <Buyer*> buyers;
};
#endif
If you had an instance of Buyer as a member of Seller (i.e., Buyer _buyer;), or if any method took/returned an instance of Buyer, you would be forced to change your structure. Since you don't have that problem, a forward declaration will suffice.
As an aside, and admitting that I am not privy to the structure of your program, it is usually a bad sign when one sees so many naked pointers being used in a C++ program. You can store instances. You can use safe pointers (shared_ptr and unique_ptr) depending on your ownership semantics.
For example, addBuyer can easily take a Buyer& instead of a pointer. Now you don't have to worry about invalid pointers. I'm assuming that you add these to your buyers vector... but how are you guaranteeing that these pointers remain valid for the lifetime of a Seller instance? You can't; you're at the mercy of whomever called addBuyer.
Why not just store a std::vector<Buyer> and take a reference in your add method? Is the cost of a copy so prohibitive as to warrant this design? If so, could you not use shared_ptr?
I'm getting this error. It's like the compiler does not recognise my declarations
g++ -c main.cc
In file included from Storage.h:7:0,
from Server.h:5,
from Control.h:8,
from main.cc:5:
Serializer.h:11:36: error: ‘Storage::UpdateType’ has not been declared
Serializer.h:12:45: error: ‘Storage::UpdateType’ has not been declared
make: *** [main.o] Error 1
Anyone have an idea what this error is about because the enum has already beeen declared. The affected code is below:
Serializer.h
#ifndef SERIALIZER_H
#define SERIALIZER_H
#include "Storage.h"
class Storage;
class Serializer{
public:
Serializer();
void serialize(List&, Storage::UpdateType&, std::string&);
void deserialize(std::string&, Storage::UpdateType&, List&);
};
#endif
Storage.h
#ifndef STORAGE_H
#define STORAGE_H
#include "List.h"
#include "Interface.h"
#include "Movie.h"
#include "Serializer.h"
class Storage{
public:
enum UpdateType {ADD, DELETE, RETRIEVE};
Storage();
~Storage();
List* list;
void retrieve(List*);
void update(UpdateType, List*);
void handleRequest(string&, string&);
private:
//Serializer serial;
};
#endif
The problem you have is that your code is interpreted as follows:
#ifndef STORAGE_H
#define STORAGE_H
// replacing the include with the Serializer.h file
#include "List.h"
#include "Interface.h"
#include "Movie.h"
// replacing the include with the Storage.h file
#ifndef STORAGE_H // returns true
#endif
class Storage;
class Serializer{
public:
Serializer();
// here Storage::UpdateType is still unknown to the compiler
void serialize(List&, Storage::UpdateType&, std::string&);
void deserialize(std::string&, Storage::UpdateType&, List&);
};
#endif
class Storage{
public:
// as it gets declared here
enum UpdateType {ADD, DELETE, RETRIEVE};
Storage();
~Storage();
List* list;
void retrieve(List*);
void update(UpdateType, List*);
void handleRequest(string&, string&);
private:
//Serializer serial;
};
#endif
the best solution, imho, would be to extract the enum UpdateType from your storage class and forward declare it in Serializer. Or even declare it within the Serializer header, as Storage is encapsulating Serializer stuff, so basically, the UpdateType stuff should be in the same encapsulated context as the Serializer stuff.
Another solution would be #Nim suggests, to include Storage from Serializer, forward declare Serializer in Storage and include Serializer in main. But it may deceives the way you have thought your design out, reversing the encapsulation of Serializer and Storage.
Finally, I'm really not sure if this is possible and how would be the syntax, but if it is, you could simply forward declare enum Storage::UpdateType in Serializer. And I guess that's what you wish would be possible.
I have a generic class for many states for an automaton. It's declared as follows:
#ifndef STATE_H_
#define STATE_H_
#include "Automat.h"
class State {
public:
virtual void readChar(char c, Automat* automat) = 0;
virtual ~State(){};
};
#endif /* STATE_H_ */
I get this error in eclipse:
Multiple markers at this line
no known conversion for argument 2 from ‘Automat* const’ to ‘int*’
virtual void State::readChar(char, int*)
‘Automat’ has not been declared
My automat is as follows:
#ifndef Automat_H_
#define Automat_H_
#include "../../Scanner/src/IScanner.h"
#include "./States/State.h"
class Automat {
public:
int count;
State* current;
IScanner* scanner;
Automat(IScanner *s);
void readChar(char c);
void setState(State *s);
void error();
~Automat();
};
#endif /* Automat_H_ */
And finally the implementation of Automat, i will leave out some methods.
#include "Automat.h"
#include "./States/StartState.h"
Automat::Automat(IScanner *s) {
current = StartState::makeStartState();
scanner = s;
count = 0;
}
void Automat::readChar(char c) {
current->readChar(c, this);
}
I do not know what causes this. do i need to declare things in an interface? Why does it want to convert the arguments?
Thank you all in advance.
Both headers try to include each other, which is impossible.
Luckily, neither class definition needs the full definition of the other. Each only deals with pointers to the other, for which only a declaration is needed. So replace
#include "Automat.h"
with
class Automat;
and likewise for State.
IMO, I would do that preprocessor stuff in the main file, and just define in each header file one variable, so you know that it's included only once. Also you could do that in "StdAfx.h" if given.
This is just a header mess, please be sure to include it only once. #pragma once may help also.