I am new to this website and I am trying a simple inheritance example in C++.
I checked my code lots of times and I really see nothing wrong with it, however the compilers gives me errors:
my code:
#ifndef READWORDS_H
#define READWORDS_H
using namespace std;
#include "ReadWords.h"
/**
* ReadPunctWords inherits ReadWords, so MUST define the function filter.
* It chooses to override the default constructor.
*/
class ReadPunctWords: public ReadWords {
public:
bool filter(string word);
};
#endif
And the messages I get from the compiler:
ReadPunctWords.h:11: error: expected class-name before '{' token
ReadPunctWords.h:13: error: `string' has not been declared
ReadPunctWords.h:13: error: ISO C++ forbids declaration of `word' with no type
Tool completed with exit code 1
I am really not sure where I get it wrong as it looks just fine to me?
Thank you for any mistakes you might spot.
You need to include string:
#include <string>
That said, don't use using namespace! Especially at file-scope, and definitely not in a header file. Now any unit that includes this file is forced to succumb to everything in the std namespace.
Take that out, and qualify your names:
bool filter(std::string word);
It's arguable more readable, too. Additionally, you should take your string as a const&:
bool filter(const std::string& word);
To avoid having to copy the string unnecessarily. Lastly, your header guards seem off. Should they be changed? As of now, they seem like the same ones that would be used in your other header, which might effectively stop it from being included.
If you define READWORDS_H and then include ReadWords.h, and if that also has:
#ifndef READWORDS_H
#define READWORDS_H
Then nothing in that file will be processed. If that's the case, ReadWords as a class won't be defined, and you cannot inherit from it. Your guard should probably be:
READPUNCTWORDS_H
You need to include <string> and specify the namespace:
#include <string>
using namespace std;
Also, your include guard should probably be named READPUNCHTWORDS_H rather than READWORDS_H.
Edit: On second thought, GMan is right about not putting using namespace in a header file - qualify the string with std::string instead.
This particular form of error is often caused by a type not being defined (at least when the code looks syntactically correct), in this case probably the class ReadWords but maybe also std::string.
You need to include to get std::string, as other posters have written, but also your guard
#ifndef READWORDS_H
#define READWORDS_H
almost certainly conflicts with the guard in ReadWords.h. You need to make sure your guards are distinct in different header files otherwise you will get conflicts like this. You should change the guard to something like
#ifndef READPUNCTWORDS_H
#define READPUNCTWORDS_H
// ...
#endif
In fact, it's better to have even more verbose guards to make sure they don't conflict. We use guards of the form
#ifndef MODULE_OR_PATH_FILE_H_INCLUDED
#define MODULE_OR_PATH_FILE_H_INCLUDED
// ...
#endif
This ensures different modules or libraries with similarly named headers don't conflict, the INCLUDED thing at the end is my own particular foible that makes the guard slightly more readable.
It's also bad practice to place a "using" declaration in a header file, because it places (potentially unwanted or conflicting) symbols in the global namespace everywhere you include the header. Personally, I prefer to retain the namespace for clarity or alias it in cpp files if it's a long one, for example
namespace fs = boost::filesystem;
also looks like something wrong with ReadWords class def (message for line 11)- we need to see .h file
aha - the sentinial def you use prevents the readwords.h include being read
you need
#ifndef _READPUNCTWORDS_H
#define _READPUNCTWORDS_H
I also suspect the include guards. If they are named the same way in both header files, the result should be something like the following when ReadWords.h is pasted into ReadPunctWords.h.
#ifndef READWORDS_H // Is READWORDS_H defined? No, proceeding
#define READWORDS_H // Now it is defined
// Contents of ReadWords.h is pasted in here
#ifndef READWORDS_H // Is READWORDS_H defined? Yes, ignoring the contents of ReadWords.h (skipping til #endif)
#define READWORDS_H
class ReadWords { ... }; // This is never seen by the compiler as the preprocessor removed it
#endif
class ReadPunctWords: public ReadWords { // Error: ReadWords isn't declared...
public:
bool filter(string word);
};
#endif
Related
I am currently working on a project where we have a shared set of headers. Now we want add some private fields without having to put those declarations directly in the shared headers.
Someone brought up the following:
namespace something {
class Foo {
public:
Foo();
void doFoo();
private:
#if __has_include("foo_private.hpp")
#include "foo_private.hpp"
#endif
};
}
Inside the _private.hpp headers we would then place the private fields for that class. When there are only default datatypes (int, bool, etc) this works fine(ish). But as soon as you put an include inside the _private.hpp file, for example #include everything breaks.
It is giving the following error expected unqualified-id before ‘namespace’ which as I understand is quite logical, since you're trying to define a namespace inside of a class.
Example _private.hpp file
#ifndef DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#define DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#include <string>
int mySecretNumber;
std::string mySecretString;
#endif
Now my question is, is there any way to trick the preprocessor, or somehow get the same results with a different solution?
namespace something {
class Foo {
public:
Foo();
void doFoo();
private:
#if __has_include("foo_private.hpp")
#include "foo_private.hpp"
#endif
};
}
If that code is including a file that looks like this:
#ifndef DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#define DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#include <string>
int mySecretNumber;
std::string mySecretString;
#endif
Then you end up with this (though in reality, the #includes themselves would resolve to the contents of <string>, etc.):
namespace something {
class Foo {
public:
Foo();
void doFoo();
private:
#ifndef DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#define DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#include <string>
int mySecretNumber;
std::string mySecretString;
#endif
};
}
Perhaps that shows your issue? You're including "string" in the middle of your class, but it needs to be included at the global namespace scope of your file.
Instead, include string at the top of the outer header, don't use include guards in the private header, and only put the body of the code you want pasted into your class into that private header. For that reason, you might not call it a ".hpp" file but something else to make it clear it's not a normal header.
Additionally, the __has_include feature seems dubious, because if your private header is missing you probably do not want it to compile to an empty class.
Worse, if you compile some translation unit that finds the header, and then compile another translation unit that does not find the private header, you will end up with two different definitions of your class, violating the One Definition Rule -- which is undefined behavior, no diagnostic required. Really nasty stuff (assuming your builds succeeds at all.)
I'm not a big fan of this kind of hiding, as it will make it hard for editors to properly show your code, to colorize and index your private header, or otherwise work with the code in a normal way. You might consider looking at the PIMPL idiom for hiding the implementation of a class in its .cpp file, so users of the header do not have to see it at all.
I am writing a class (separated in header file myClass.h and implementation file myClass.cpp) which I want to use with both standard C++ and the Qt framework. Since the differences in the code are very small (and I wanted to try it out once), I decided to #define USINGQT 1 in order to toggle the small sections of code via
#if USINGQT==1
//Qt code
#else
//standard code
#endif
Now I came to the conclusion that it'd be convenient to use QStrings throughout the whole class instead of std::strings when "activating" the USINGQT switch. However, the method above would render the code extremely messy. My solution (in the header file):
#if USINGQT==1
#include <QString>
#define string QString
#else
#include <string>
#define string std::string
#endif
Now to the question:
Consider the files to look like
---myclass.h-------------------------
#ifndef MYCLASS_H
#define MYCLASS_H
#define USINGQT 1 //1=on, else off
#if USINGQT==1
#include <QString>
#define string QString
#else
#include <string>
#define string std::string
#endif
namespace mySpace {
class MyClass {
string qtOrStd;
string foo();
//etc...
};
} //namespace
#endif //MYCLASS_H
-------------------------------------
---myclass.cpp-----------------------
#include "myclass.h"
using namespace mySpace;
//implementations
string MyClass::foo() //string symbol occurs, as does the USINGQT
-------------------------------------
Where is the correct place to #undef the string and USINGQT symbols? At the end of the header file (which would then require a redefinition and "undefinition" in the implementation file as well) or just at the end of the implementation file?
I should capitalize the string macro as well, shouldn't I...? >.>
If I put the macro definitions inside the namespace I receive approx. 800 error messages with entries like "no member of mySpace::std" among others. Can you say something about that without further information? Otherwise it compiles just fine.
EDIT: I may should have told you that I want the macros to only apply to this specific header AND its implementation file. Despite the fact that I will of course go for the typedefs - in the macro case, I'd guess, I should place the #undef at the end of the implementation file. Because the macros won't be redefined because of the include guards.
Firstly you do not need to toggle USINGQT by making it equal to 1 you can simply #define USINGQT and then use #ifdef USINGQT for your if statement.
In terms of your ability to toggle which string library you use I would suggest using a typedef alongside a pre-processor if statement. This would avoid any namespace issues. An example of this is shown below.
// -------------- Some config file -------------=
#define USINGQT
// -------------- MyClass.h --------------------=
// Header guard
#ifndef MyClass
#define MyClass
// Conditional Header types
#ifdef USINGQT
// QT OPTION
typedef QString my_string;
#else
// Not QT
typedef std::string my_string;
#endif
class MyClass {
public:
my_string some_string;
MyClass()
{
my_string = "hello world";
}
};
#endif
I do not see any reason to #undef the macro. Surely you want all your code to be compiled with one state of that macro? Then you will not need to #undef it.
However, I also strongly suggest you to use typedef for your string definition. This will anyway be clearer, you will not think about capitalizing it, and you can even put it into your namespace. Use :: if you need to access global namespace:
#define USINGQT
#ifdef USINGQT
#include <QString>
#else
#include <string>
#endif
namespace mySpace {
#ifdef USINGQT
typedef ::QString string;
#else
typedef ::std::string string;
#endif
}
Also note (as shown above) that if you need just a boolean value for macro, then you don't need to make it 1 or 0, just use #ifdef/#ifndef.
After this, in your .cpp, just use mySpace::string and never bother about macroses.
You don't have to #undef macros unless another file tries to re-define it. You can't #undef a macro before you're done using it and therefore, if you #define a macro in a header and want to use it in files that include the header, then you cannot #undef it in that header.
1) Where is the correct place to #undef the string and USINGQT symbols? At the end of the header file ...
Only if you use it in that header... but you apparently do use it a file that includes the header, so no.
or just at the end of the implementation file?
Undefining a macro at the end of an implementation file is pointless, because there will be no code after the end of the file to which the macro applies anymore. Just let it stay defined.
2) I should capitalize the string macro as well, shoudln't I...? >.>
You don't have to capitalize macros, but it's a convention. That said, defining a macro by the same name as a standard class is just asking for trouble. You should use a typedef instead of a macro here in order to get meaningful error messages in case of name conflicts. And use another name like string_t or define the typedef in a namespace.
3) If I put the macro definitions inside the namespace I receive approx. 800 error messages
The errors don't come from defining the macros inside a namespace. The errors come from using the macros as-if they were part of the namespace. For example, if you say:
namespace mySpace {
#define string std::string
}
mySpace::string s;
then the string will be replaced with std::string and the typename becomes mySpace::std::string. Since you haven't defined a std namespace inside mySpace, this is wrong. What you need to understand is that namespaces don't have any effect on preprocessor macros. Which makes it harder to avoid name conflicts which is one reason why you usually want to avoid pre-processor macros.
If the USINGQT macro applies to all of your code such that it must be same for all files, you may want to not define it in a header at all, but instead pass it as an argument to the compiler. That way you can easily compile with different values without changing a file.
About your edit:
Even if you want the macro to be defined differently in another file, then undefining it at the end of the implementation has no effect, because the implementation file won't be included by the files that include the header. You should avoid a situation where you need multiple, different definitions (or lack of definitions) of macros, but if you're in such a situation, then yes, your only solution is to define it separately in each file that needs it and then undefine at the end of any header that needs it. But you're not in a such situation because you can use a type alias instead.
I am getting stuck using this class, when I used in the main.cpp there is no problem and execute perfectly, but when I use it as a member class the compiler doesn't like it and sends the message "Multiple definition of:"
Here is the class:
RTPSocket.h:
#ifndef RTP_SOCKET_HDR
#define RTP_SOCKET_HDR
namespace RTPConnection
{
enum EMode
{
Sender,
Receiver
};
template<EMode Mode>
class RTPSocket
{
};
}//end namespace
#define RTP_SOCKET_IMP
#include "RTPSocket_Imp.h"//file where i declare the implementation code
#undef RTP_SOCKET_IMP
#endif
this class by itself doesn't have any problem but when i use it in my class, but ....
used in another class
my file.h
#include RTPSocket.h
class CommClass
{
private:
RTPSocket<RTPConnection::Receiver> * mRTPServer;
}
the compiler give this error message:
multiple definition of 'enum RTPConnection::EMode'
this is a method that is declared in another file "rtpsocket_imp.h"
with the guard declared:
template<EMode Mode>
void RTPSocket<Mode>::write(char* aArray,
const size_t aiSize)
{
std::string message("The write function is operative only on Sender Mode");
throw BadTemplate(message);
}
You want include guards around the header:
#ifndef RTPSOCKET_H
#define RTPSOCKET_H
// header contents go here
#endif
This will prevent the header contents from being included more than once per source file, so you will not accidentally get multiple definitions.
UPDATE: Since you say you have include guards, then possible causes of the error might be:
misspelling the include guard name, so it doesn't work
defining something with the same name in another header (or the source file that includes it)
undefining the include guard name.
But without seeing code that reproduces the error, I can only guess what might be wrong.
You need an include guard.
Inside the RTPSocket.h file at the top put
#ifndef RTPSOCKET_INCLUDED
#define RTPSOCKET_INCLUDED
and at the end put
#endif
If that's not the problem, and you do have an include guard, I suggest you search for
enum EMode
in your code and find all the places you have defined it, and make sure you just define it once.
My problem was the CMakeLists.txt that was building this project.
My fault!
I have two functionally identical header files, one of which produces errors for no discernible reason. I must have done something wrong in creating the new (broken) file, but I can't figure out what.
My IDE is Xcode. The project is compiled for Objective C++ using Apple LLVM Compiler 4.1, but the section of code in question is all pure C++, no Objective C.
Here's some code:
NamespaceA.Common.h
#include "../NamespaceB/Common.h"
#include "WorkingClass.h"
#include "BrokenClass.h"
...
../NamespaceB/Common.h
#ifndef NamespaceBCommon
#define NamespaceBCommon
namespace NamespaceB
{
...
}
...
#include "Superclass.h"
...
WorkingClass.h
#ifndef NamespaceA_WorkingClass
#define NamespaceA_WorkingClass
namespace NamespaceA
{
class WorkingClass : public NamespaceB::Superclass
{
public:
WorkingClass();
~WorkingClass();
};
}
#endif
BrokenClass.h
#ifndef NamespaceA_BrokenClass
#define NamespaceA_BrokenClass
// If I don't have this line I get errors. Why?? !!!!!
// This file is exactly identical to WorkingClass.h
// as far as I can tell!
//#include NamespaceA.Common.h
namespace NamespaceA
{
// Parse Issue: Expected class name !!!!!
// Semantic Issue: Use of undeclared identifier 'NamespaceB'
class BrokenClass : public NamespaceB::Superclass
{
public:
BrokenClass();
~BrokenClass();
};
}
#endif
Thank you.
You need to include all of the files that include namespaces and classes that you reference in your code. So, because you reference NamespaceB::Superclass in your BrokenClass.h, you need to be sure to include the file that declares that. In this case, including NamespaceA.Common.h (hopefully) solves this problem, because it includes the file where NamespaceB is included.
As for why you don't have to include NamespaceA.Common.h in your WorkingClass.h, I suspect it's because you just happen to have ../NamespaceB/Common.h included somewhere else.
I found the problem. WorkingClass.cpp was including NamespaceA.Common.h and not including its own header file, rather than including the common file in the header and then including its own header file in the cpp.
I managed to miss the #include in WorkingClass.cpp because I just assumed it was only including WorkingClass.h and not NamespaceA.Common.h.
So in short:
WorkingClass.h
// Class goes here
// No includes
WorkingClass.cpp
// Notice it does not include WorkingClass.h for whatever reason
#include "NamespaceA.Common.h"
NamespaceA.Common.h
#include "../NamespaceB/Common.h"
#include "WorkingClass.h"
#include "BrokenClass.h"
#include "EveryOtherClass.h" ...
BrokenClass.h
// Class goes here
// No includes
BrokenClass.cpp
#include "BrokenClass.h"
// Oh no! Where's NamespaceA.Common.h?
I'm not a big fan of this include scheme, but I'll live with it since it's a large project that I don't want to make sweeping changes to.
I am making a small game.
In BattleRecord.h:
#ifndef _CHARACTER_H_
#define _CHARACTER_H_
#include "Character.h"
#endif
class BattleRecord
{
public:
Character Attacker;
Character Defender;
Status status;
int DamageDealt;
int GoldEarned;
int ExpGained;
};
In Character.h:
#ifndef _EQUIPMENT_H_
#define _EQUIPMENT_H_
#include "Equipment.h"
#endif
class BattleRecord;
class Character
{
BattleRecord AttackEnemy(Character &Enemy);
}
In BattleRecord.h:
#ifndef _CHARACTER_H_
#define _CHARACTEr_H_
#include "Character.h"
#endif
#ifndef _BATLE_RECORD_H_
#define _BATLE_RECORD_H_
#include "BattleRecord.h"
#endif
class GUI
{
public:
//GUI Methods, and two of these:
void ViewStats(Character &Player);
void Report(BattleRecord Record)
}
The problem here is, my Character.h and BattleRecord.h need to include each other, and this definitely will cause multiple redefinition problem. Therefore, I used forward declaration in Character.h by adding:
class BattleRecord;
The problem is sovled. But then, the GUI.h needs BattleRecord.h again for reporting the battle, so I have to include BattleRecord.h into the GUI.h. I also have to include the Character.h in order to pass into the ViewStat function. I got error and stuck with this up to this piont.
You're using inclusion guards wrong. They should appear in the file that you intend to prevent multiple inclusions only, and they should cover the entire file. (not just the includes).
For example, in BattleRecord.h
#ifndef _BATTLE_H_
#define _BATTLE_H_
#include "Character.h"
class BattleRecord
{
public:
Character Attacker;
Character Defender;
Status status;
int DamageDealt;
int GoldEarned;
int ExpGained;
};
#endif // _BATTLE_H_
Put your #endif at the end of the file not the end of your includes or use #pragma once at the top if your compiler supports this although that is less portable.
Edit:
To further explain what #ifdef & ifndef does is tell the compiler to include or exclude code entirely from compilation.
// if _UNQIUEHEADERNAME_H_ is NOT defined include and compile this code up to #endif
#ifndef _UNQIUEHEADERNAME_H_
// preprocessor define so next time we include this file it is defined and we skip it
#define _UNQIUEHEADERNAME_H_
// put all the code classes and what not that should only be included once here
#endif // close the statement
The reason you want to do this is because including a header file is basically saying "put all the code in this file here" if you did that multiple times then you'd have naming conflicts from redefining objects and slow compile times in the best scenario.
In general, use forward declaration instead of includes. This minimizes how many includes you include file contains. The only exception is when the class you are defining is a derived class, then you need to include the base class.
In addition to the include guard issues mentioned above (you also have a _CHARACTEr_H_/_CHARACTER_H_ mismatch that might cause you trouble on line 2 of GUI.h), you may want to revise your object design so that the Character does not AttackEnemy(), but rather there is a Battle() class where two Characters are referenced and a BattleRecord is produced after the battle. This would prevent the Character class from ever having to know about BattleRecords in the first place, would allow for the possibility of multi-Character battles in the future, having multi-turn battles, or having special battles through inheritance of the Battle class.
OK everyone,
Thanks for helping me. I have rewritten all the inclusions for the header files as suggested, and it works flawless now. Take quite time a bit of time since I did it wrong for many classes.