I have this annoying error in my program.
"Vehicle" is the Base class.
"Bicycle" extends this class.
#ifndef BICYCLE_H
#define BICYCLE_H
#include "Vehicle.h"
#include <string>
#include <iostream>
using namespace std;
//Template class which is derived from Vehicle
template<typename T>
class Bicycle: public Vehicle
{
public:
Bicycle();
Bicycle(int, int, string, int);
~Bicycle();
//Redefined functions inherited from Vehicle
void move(int, int); // move to the requested x, y location divided by 2
void set_capacity(int); // set the capacity value; can't be larger than 2
};
Above is the Bicycle.h file (I do not have .cpp file for this class)
#ifndef VEHICLE_H
#define VEHICLE_H
#include "PassengerException.h"
#include <string>
#include <iostream>
using namespace std;
//ADD LINE HERE TO MAKE IT A TEMPLATE CLASS
template<typename T>
class Vehicle
{
public:
Vehicle(); //default contstructor
Vehicle(int, int, string, int); // set the x, y, name, and capacity
virtual ~Vehicle(); //destructor; should this be virtual or not???
//Inheritance - question #1; create these functions here and in Bicycle class
string get_name(); // get the name of the vehicle
void set_name(string); //set the name of the vehicle
void print(); // std print function (GIVEN TO YOU)
//Polymorphism - question #2
virtual void move(int, int); // move to the requested x, y location
virtual void set_capacity(int); // set the capacity value
//Operator overloading - question #3
Vehicle<T> operator+(Vehicle<T> &secondVehicle) const;
//Exceptions - question #4
T get_passenger(int) throw(PassengerException); // get the passenger at the specified index
void add_passenger(T) throw(PassengerException); // add passenger and the current passenger index
void remove_passenger() throw(PassengerException); // remove a passenger using current passenger index
protected:
int x_pos;
int y_pos;
string name;
int capacity;
T *passengers;
int current_passenger;
};
Above is the Vehicle.h file. I do not have .cpp for this either.
Also, what do the ifndef define endif mean? Do I have to use those? Are they required?
And, do their names have to be formatted like that?
class Bicycle: public Vehicle
Vehicle is a template, so you need this:
class Bicycle: public Vehicle<T>
The #ifndef and #define and #endif are called header guards and are used to prevent your header file from being included more than once, causing things (classes) to be declared more than once.
The ifndef define and endif are necessary for the actual base files, i.e. the c++ files themselves. Yes they are required, if you plan to use those functions and variables accordingly. Yes, their names have to be formatted that way, that's the way directives or in some cases flags must be formatted.
You have to put #endif at the end of your header files. These are so called define guards to prevent multiple inclusion of header files. See more at Include guard.
Related
I´m building a program with several classes (data structures like stacks, lists,etc).
There is some class (Concesionario) that i need to use in another (ListaE). The class ListaE uses another class called NodoListaE, which uses two pointers, one to the value of the object (Concesionario) and another to the next position of the list (siguiente).
#ifndef NODOLISTAE_HPP
#define NODOLISTAE_HPP
#include "Concesionario.hpp"
class Concesionario;
class ListaE;
class NodoListaE
{
public:
NodoListaE(Concesionario* conc, NodoListaE* sig = NULL);
private:
Concesionario* conc;
NodoListaE* siguiente;
friend class ListaE;
};
typedef NodoListaE* pnodoListaE;
#endif // NODOLISTAE_HPP
#ifndef LISTAE_HPP
#define LISTAE_HPP
#include "NodoListaE.hpp"
#include "Automovil.hpp"
class Automovil;
class NodoListaE;
class ListaE
{
private:
NodoListaE* primero;
public:
ListaE();
void enlistarOrden(Automovil* automovil);
};
#endif // LISTAE_HPP
#ifndef CONCESIONARIO_HPP
#define CONCESIONARIO_HPP
#include <string>
#include "ListaE.hpp"
class ListaE;
class Concesionario
{
public:
Concesionario();
~Concesionario();
std::string mostrar();
void setZona(std::string letra);
void setNum();
int getNum();
private:
int nc=2;
int num_conc;
std::string zona;
int generadorNumsIntervalo(int min, int max);
ListaE automoviles;//ERROR HERE
};
#endif // CONCESIONARIO_HPP
All the cpp files are not implemented (empty constructor and destructor).
The compiler I´m currently using is MINGWx64.
I´ve tried using forward declarations and it worked for the rest of the classes but not for this one.
The program throws the following error in the **Concesionario ** hpp file: include\Concesionario.hpp|22|error: field 'automoviles' has incomplete type 'ListaE'|
Concesionario is implemented in other classes and the program runs perfectly.
Example of another class implementing Concesionario
#ifndef ARBOL_HPP
#define ARBOL_HPP
#include <iostream>
#include "NodoArbol.hpp"
#include "Concesionario.hpp"
using namespace std;
class Arbol {
public:
Arbol();
void Insertar(Concesionario* concesionario);
private:
pnodoArbol raiz;
pnodoArbol actual;
int contador;
int altura;
bool Vacio(pnodoArbol nodo);
};
#endif // ARBOL_HPP
I`ve also tried deleting this class and creating another one from 0 but the error remains.
Any solution to this problem? Thank you very much.
I'm a first-year college student that doesn't know everything about CS yet, so please bear with my newness to it, and this is my first question on here.
For an assignment, we are making faux version of Pokemon Go to practice using polymorphism in c++, and I'm running into some compiler errors. Here are the three files with just a sample of the code in them:
#ifndef EVENT_H
#define EVENT_H
#include <string>
#include "Trainer.h"
class Event{
protected:
std::string title;
public:
Event();
~Event();
virtual void action(Trainer) = 0;
};
#endif
Trainer.h:
#ifndef TRAINER_H
#define TRAINER_H
#include "Pokemon.h"
class Trainer{
private:
Pokemon* pokemon;
int num_pokemon;
public:
Trainer();
~Trainer();
//include accessors and mutators for private variables
};
#endif
Pokemon.h:
#ifndef POKEMON_H
#define POKEMON_H
#include "Event.h"
#include <string>
class Pokemon : public Event{
protected:
std::string type;
std::string name;
public:
Pokemon();
~Pokemon();
virtual bool catch_pokemon() = 0;
};
#endif
The trainer.h file is a parent class for each pokemon type (eg Rock) which just defines a few virtual functions. The error I'm getting is when I'm compiling all of this and I get something that says:
Pokemon.h : 5:30: error: expected class-name befoer '{' token:
class Pokemon : Event {
Pokemon need to be a derived class to an event, so that an event pointer can point in another Location class can point to either a pokemon, pokestop, or cave for the assignment, and I have been looking online for hours and can't figure out what to do. I would appreciate the help! Let me know if you need more info or something because again, this is my first time posting a question.
You need some forward declarations.
In Event.h, you can put class Trainer; instead of #include "Trainer.h". In Trainer.h, you can put class Pokemon; instead of #include "Pokemon.h".
You will probably need to include the appropriate headers in the corresponding source files in order to actually use the other classes. But by avoiding the includes in the header files, you get out of the circular dependency trouble.
Pokemon.h must continue to #include "Event.h", since you're inheriting Event, which requires a complete definition.
Use forward declaration, to tell classes the type they need to use will be defined later. You can use forward declaration in situations where the size is know, pointers and references are always the same size regardless of the type they point to so use them.
#ifndef EVENT_H
#define EVENT_H
#include <string>
class Trainer;
class Event
{
protected:
std::string title;
public:
Event();
virtual ~Event();
virtual void action(Trainer* const trainer) = 0;
};
#endif
then
#ifndef TRAINER_H
#define TRAINER_H
class Pokemon;
class Trainer
{
private:
Pokemon* const pokemon;
int numPokemon;
public:
Trainer();
~Trainer();
};
#endif
then
#ifndef POKEMON_H
#define POKEMON_H
#include "Event.h"
#include <string>
class Pokemon : public Event
{
protected:
std::string type;
std::string name;
public:
Pokemon();
virtual ~Pokemon();
virtual bool catchPokemon() = 0;
};
#endif
when using polymorphism (virtual functions) you must always make the base class destructor virtual too. It is also nice to make the derived classes destructor virtual as well, but it is not required.
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
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 dynamic array-based class that I'm calling MyList, that looks as follows:
#ifndef MYLIST_H
#define MYLIST_H
#include <string>
#include <vector>
using namespace std;
template<class type>
class MyList
{
public:
MyList();
~MyList();
int size() const;
type at() const;
void remove();
void push_back(type);
private:
type* List;
int _size;
int _capacity;
const static int CAPACITY = 80;
};
#endif
I also have a another class that I'm calling User that I want to include an instance of MyList as a private data member. User looks like this:
#ifndef USER_H
#define USER_H
#include "mylist.h"
#include <string>
#include <vector>
using namespace std;
class User
{
public:
User();
~User();
private:
int id;
string name;
int year;
int zip;
MyList <int> friends;
};
#endif
When I try to compile I get an error in my user.cpp file:
undefined reference to MyList::Mylist()
I find this odd because MyList is completely unrelated to user.cpp, which only contains my User constructor and destructor.
Make sure that you write both the declaration and the definition of your template class into the header (define MyList in the header not in a .cpp file)
The reason is that you did not provide MyClass<int> constructor definition. Unfortunatelly in C++ you cannot divide template class definition by declaring methods in header file and defining them in the implementation. At least if you want to use it in other modules. So in your case User class needs to have MyClass<int>::MyClass() definition right now. There are two ways to do it:
(the easiest one) provide constructor definition right in place:
MyClass() {
...
} or
add method definition in MyClass.h after class definition like that:
template<class type> MyList<type>::MyList() {
...
}