I have two errors that arise on the same line of code.
The following are snippets, only relevant code is there.
First is Database Class
#include "program.h"
using namespace std;
class Database {
public:
Database(Program *program);
~Database();
};
Next is the Query Class.
#include "database.h"
using namespace std;
class Query {
public:
Relation* evaluate(Database* database);
};
The line in question is:
Relation* evaluate(Database* database);
The first error is "Database does not name a type", despite including the database.h file.
The second error is "expected ';' after member declaration" which I believe is related to the first.
Everything in this project has worked until the addition of this database class.
I am stumped on this one, and have been researching all over stackoverflow to no avail.
I am on Debian Stretch and compiling with g++. Does anyone have any ideas?
EDIT
Minimal compilable code:
query.h
#include "database.h"
class Query {
public:
void evaluate(Database* database);
};
program.h
#include "query.h"
#include "database.h"
using namespace std;
class Program {
public:
};
database.h
#include "program.h"
class Database {
public:
Database(Program *program);
};
You might want to try out the -E option of the compiler: it causes the source code to be preprocessed, i.e., you'll see the code as it is seen by the compiler. If you look at your headers closely you'll see that there are cyclic dependencies between the different types. You'll need to break them.
The "easy" fix is to declare the Database class in query.h:
class Database;
class Query {
public:
void evaluate(Database* database);
};
While this will fix the shown problem, cyclic dependencies will come and haunt you. In general they are bad. A system of class which cyclicly depend on each other are effectively just one component and should probably be all declared in just one header.
Related
I’m trying to do a basic polymorphism program and am having some problems.
I have 2 files, Currency.cpp and Dollar.cpp
Currency.cpp looks something like this
#include <iostream>
using namespace std;
class Currency{
/* code */
};
Dollar.cpp looks something like this
#include <iostream>
using namespace std;
class Dollar : protected Currency{
/* code /*
};
When I try to build paths between the files (command shift b on mac) it tells me that Currency is not recognized as a class (in Dollar.cpp that is). I’m not supposed to use header files as this is for an assignment that specifies so. What am I supposed to do?
I use vs code on a 2020 m1 Mac if that has anything to do with it
Edit:
Thanks for all the feedback. From what I can tell what I'm asking here isn't possible. This assignment is for a data structures and algorithms class that accepts multiple languages, so maybe the teacher is rusty in c++ or something. I'm just gonna use header files and the professor will just have to deal with it lol.
I’m not supposed to use header files as this is for an assignment that specifies so.
The code will not work as shown. Dollar.cpp needs to know what the Currency class looks like in order to use it.
The ideal solution is to use a header file to share declarations across translation units, use the .cpp files to implement definitions, eg:
Currency.h:
#ifndef CurrencyH
#define CurrencyH
class Currency{
/* code */
};
#endif
Currency.cpp:
#include <iostream>
#include "Currency.h"
using namespace std;
// implement Currency's methods as needed...
Dollar.cpp:
#include <iostream>
#include "Currency.h"
using namespace std;
class Dollar : protected Currency{
/* code /*
};
But, since that is not an option for you, you have no choice but to copy the entire Currency class declaration into Dollar.cpp directly, and make sure it exactly matches the class declaration in Currency.cpp to avoid any ODR violations, eg:
Currency.cpp:
#include <iostream>
using namespace std;
class Currency{
/* code */
};
// implement Currency's methods as needed...
Dollar.cpp:
#include <iostream>
using namespace std;
class Currency{
/* code */
};
class Dollar : protected Currency{
/* code /*
};
For teaching purposes in my applied oriented object courses, we are asked to develop a fully featured C++ application without using the STL nor any string manipulation functions from cstring (SDL for GUI will be involved in a later stage).
While redeveloping simple String and list container hierarchy classes, I encountered a cyclical dependency issue. Previously, I fixed these kind of issues using forward declaration. However, this time, things do not go as expected and this problem kept me busy for a few evenings now.
Here is a simple UML diagram of the issue I have.
Every class has their own .cpp and .hpp files, except for BaseListItemNotFoundException I declare with a using statement above the BaseList class declaration.
class BaseListItemNotFoundException: BaseException {
using BaseException::BaseException;
};
Even if this doesn't add any added pieces of info (IMHO), let me precise BaseList and HeplList classes are actually template classes defined using .ipp and .hpp.
I omitted some other classes involved to restrict the environment to a minimal working example (iterator and Cell generic class hierarchy used as payload for the lists). Header protections using define and ifndef conditions have been removed for clarity.
Here are a snipped of the files:
BaseList.hpp:
#include <cstddef>
#include <iostream>
#include "Cell.hpp"
class HeplString; // Forward declaration
#include "BaseException.hpp"
class BaseListItemNotFoundException: BaseException {
using BaseException::BaseException;
};
template<class T>
class BaseList {
// code
};
HeplList.hpp:
#include <cstddef>
#include "BaseList.hpp"
#include "Cell.hpp"
template<class T>
class HeplList : public BaseList<T> {
// code
};
#include "HeplList.ipp"
HeplString.hpp:
#include <cstddef>
#include <iostream>
#include <ostream>
#include <fstream>
#include "HeplList.hpp"
class HeplString {
// code
};
BaseException.hpp:
#include "HeplString.hpp"
#include "BaseList.hpp"
class BaseException {
// code
};
The main issue I have with this example is errors like this one:
src/tests/../BaseException.hpp:9:20: error: field ‘msg’ has incomplete type ‘HeplString’
HeplString msg;
^~~
In file included from src/tests/../HeplList.hpp:5,
from src/tests/../HeplString.hpp:9,
from src/tests/test.cpp:2:
src/tests/../BaseList.hpp:9:7: note: forward declaration of ‘class HeplString’
class HeplString;
^~~~~~~~~~
I don't understand what I'm doing wrong here. Reading other similar issues didn't help.
My git repository with the full code is available here, if needed: https://github.com/wget/hepl-2-cpp
Add #include "BaseException.hpp" to BaseList.hpp
Add #include "HeplList.hpp" to HeplString.cpp
Add the forward declaration template<class T> class HeplList; to HeplString.hpp
Now, you may need to modify some of your other classes which weren't including the BaseList.hpp header because they were relying on the header HeplString.hpp to do this for them.
I have a multifile program, and I can't figure out why my program says that "Customers" (in the registerNewUser() function) is an undeclared identifier.
proc.h
#ifndef PROC_H
#define PROC_H
#include <iostream>
#include "const.h"
#include "customers.h"
#include <fstream>
using namespace std;
void registerNewUser(Customers cBase); // Add new user.
#endif // !PROC_H
I have included the header file (customers.h) with the Customers class also.
customers.h
#ifndef CUSTOMERS_H
#define CUSTOMERS_H
#include <iostream>
#include "const.h"
#include "proc.h"
#include "customer.h"
using namespace std;
class Customers {
private:
char* current;
List* customerList; // List for customers.
public:
Customers(); // Constructor.
~Customers(); // Destructor.
void handler(); // Customers handler/menu.
void addNew(char username[]);
};
#endif // !CUSTOMERS_H
Can anyone see what's wrong?
You have a circular include. customers.h includes proc.h so basiacally
void registerNewUser(Customers cBase);
Will get added to customers.h before the compiler has seen what a Customer is. It looks like you should just be able to remove the #include "proc.h" in customers.h and it should compile.
As stated in the comments above you should never use using namespace std; in a header file as anything that includes it now has the entire std namespace exposed. You should also get in the habit of only using it in the most narrow scope you can or drop it completely. For further reading on the use of using namespace std; see Why is “using namespace std” in C++ considered bad practice?
Basically including "customers.h" in "customers.h" wouldn't be a problem here, since you have a guard (plus point for that). Nevertheless it is not very nice.
As NathanOliver said it COULD be a problem with the order of the includes but it doesn't have to. If you include proc.h first everything is fine. If you include customers first, the compiler includes proc.h before he sees the customer class. proc then wont include customers.h (since its guard prevents it). Then he will find your function not knowing what "Customer" means. So depending on the include order of your header files it will or will not work.
If you want a hint: I normally first only include the necessary files for a forward declaration, then do a forward declaration. Then I include the files necessary files for the definition of the class (These will already know that the class exists). The complete class declaration (with member function declaration) follows. If you do it like this you can avoid many mistakes. In your case:
#ifndef CUSTOMERS_H
#define CUSTOMERS_H
class Customers;
#include "proc.h"
#include "ListTool2B.H"
using namespace std;
class Customers
{
private:
char* current;
List* customerList; // List for customers.
public:
Customers(); // Constructor.
~Customers(); // Destructor.
void handler(); // Customers handler/menu.
void addNew(char username[]);
};
#endif
This is probably a duplicate: you have proc.h including customers.h and customers.h including proc.h this will cause a circular reference, and looks like proc.h included in customers is not necessary, so you could try simply to delete this line:
#include "proc.h"
I have a problem compiling multiple files with codeblocks. My problem is that the compiler doesnt recognize the class types that i created. I get the error doesnt name a type. I have add at all header files the #ifndef, #deffine. My files are:
forum.h
#include <list>
#include "thread.h"
class Forum
{
private:
std::list<Forum*> forums;
std::list<Thread*> themata;
}
thread.h
#include <list>
#include "forum.h"
#include "post.h"
class Thread
{
private:
Forum* forum; //gia tin allagi thesis otan ginei stick
int id;
std::list <Post*> lista;
}
post.h
#include "system.h"
class Post
{
private:
System* system;
}
What can i do for that ?
You have a circular header dependency. Use forward declarations to break it. For example, in forum.h, forward declare the Thread class instead of including its header like this:
#include <list>
class Thread;
class Forum
{
private:
std::list<Forum*> forums;
std::list<Thread*> themata;
};
Include the header in forum.cpp.
I have a class which is going to handle an array of objects of another class I've created earlier (which works fine). The problem appears when I try to create an object of my List-class.
This is the header of the list-class:
#ifndef personlistH
#define personlistH
#include "Person.h"
#include <iomanip>
#include <iostream>
#define SIZE 10
namespace std {
class PersonList {
private:
Person persons[SIZE];
int arrnum;
string filename;
public:
Personlist();
};
}
#endif
This is the main function:
#include <iostream>
#include "PersonList.h"
using namespace std;
int main() {
PersonList personlist;
return 0;
}
The error my compiler is giving me is the following:
error: "27 \PersonList.h ISO C++ forbids declaration of `Personlist'
with no type"
I've searched for answers but as I'm quite new to C++ it's been a bit confusing and I haven't found any fitting yet. It would be great if you could explain this error for me.
You have the wrong capitalisation on your constructor declaration. You have Personlist(); but need PersonList();. Because what you have isn't equal to the class name it is considered a function rather than a constructor, and a function needs a return type.
Do not add your own types to the standard namespace(std), instead create your own namespace and define your class inside it.
//PersonList.h
namespace PersonNamespace
{
class PersonList
{
//members here
};
}
//Main.cpp
using namespace PersonNamespace;
The actual error is that you made a typo in Personlist instead of PersonList
The error is because you got the capitalisation wrong when you declared the constructor; it should be PersonList() not Personlist().
Also, you should never declare your own classes in the std namespace; that's reserved for the standard library. You shoud make up your own namespace name, and put your things in that.