I'm current building an application in which I have a log function that is accessible in most of my classes which was declared as below:
FileHandler.h
#ifndef FILEHANDLER_H
#define FILEHANDLER_H
#pragma once
#include <SDL.h>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <cctype>
//Include to allow logging
#include "log.h"
class fileHandler
{
public:
fileHandler();
virtual ~fileHandler();
void WriteToFile(const std::string& filename, std::string textToWrite);
std::vector<std::string> ReadFromFile(const std::string& filename);
std::string& TrimString(std::string& stringToTrim);
protected:
private:
class log logHandler;
std::vector<std::string> blockOfText;
std::string currentLine;
};
#endif // FILEHANDLER_H
Log.h
#ifndef LOG_H
#define LOG_H
#pragma once
#include <SDL.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <time.h>
class log
{
public:
log();
virtual ~log();
void static WriteToConsole(std::string textToWrite);
void WriteToLogFile(std::string textToWrite);
protected:
private:
};
#endif // LOG_H
This worked fine for a long time and then I wanted to include another function elsewhere in my application that was only compatible with C++11 so I told the compiler to compile to these standards. I was then receiving an error on "log logHandler" saying log is not a declared name.
I was able to resolve the problem by changing the line to
class log logHandler;
I was wondering if anybody could tell me what has changed between C++03 and C++11 that required me to do this?
EDIT: Included all relevant code to make question more complete.
You don't show your real code (missing ; at the end of the class declaration, no #endif), but chances are that your problem is somehow related to std::log, which has received a new overload in C++11, in combination with a using namespace std somewhere in your code.
Note that the new overload is probably irrelevant to the problem at hand; the real reason may very well be a change somewhere in your compiler's standard-library implementation causing an internal #include <cmath>. This means that even in C++03, your code was only working by sheer coincidence, and a conforming C++03 compiler was always allowed to reject it.
Here is an example program which may reproduce your problem:
#include <cmath>
using namespace std;
struct log
{
};
int main()
{
// log l; // does not compile
struct log l; // compiles
}
Nothing has changed about how the code you posted is treated.
What I suspect is, that you somewhere have an
#include <cmath>
And below that, somewhere else
using namespace std;
This causes your compiler to not be able to unambiguously resolve the name log, since there is std::log (a function) and your class log.
By explicitly stating class log, you tell the compiler that you are referring to the class.
Related
I am attempting to make a class to contain some math operations from a CRC math tables handbook I have, in creating one of the functions I got a strange error I had not seem before. The code for both the cpp and the header are below:
//Header File
#include <iostream>
#include <cmath>
#include <string>
#define int "CRCMathLib_H"
using namespace std;
class CRCMathLib
{
public:
int DoReturn_Totient(int Toter); //Error comes from here when trying to declare as an int
};
//CPP Class File
#include "CRCMathLib.h"
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
int CRCMathLib::DoReturn_Totient(int Toter)
{
return 0;
}
//CPP Main File
#include <iostream>
#include <cmath>
#include <string>
#include "CRCMathLib.h"
using namespace std;
int main()
{
return 0;
}
The Main file does not do anything as of yet as this is a completely new file for these operations, I believe this may be a preprocessing error and its not picking up on the int statement as I ran it on another PC with VS and it was able to read the statement. anything would help. Also it was requesting a decleration of the header file, so thats why I placed the int there, is this possibly the issue? removing it returns the error of not having a decleration.
In your .h remove #define int "CRCMathLib_H" which is most probably a typo
replace it by
#include <iostream>
#include <cmath>
#include <string>
#pragma once
The #pragma once ensure you can safely include your .h from the cpp implementation file and the main.cpp
You mis understood include guard protection usually done by
ifndef CRCMathLib_H
#define CRCMathLib_H
// all of you .h file delcaration
#endif
This can be easily replace by the #pragma once statement at the begining of the file
More on this here: https://www.learncpp.com/cpp-tutorial/header-guards/
I've been creating codes using C++ STL. And I want to use "queue".
So, I wrote the codes like below.
But, I encountered "queue is not a template" error.
As you can see, I wrote headers related with queue (iostream, queue) in "Common.h" file and wrote include "Common.h" in "DataQueue.h" file. But, VS2013 IDE tool said that 'queue m_deQueue' is error because queue is not a template. I don't know why.. this error occured. Any help is appreciated!
//[Common.h]
#ifndef _COMMON_
#define _COMMON_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
//thread related headers
#include <Windows.h>
#include <process.h>
//socket related headers
#include <winsock.h>
#include <iostream>
#include <queue>
#include <deque>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
#endif
//[DataQueue.h]
#ifndef _QUEUE_
#define _QUEUE_
#include "SocketStruct.h"
#include "Common.h"
class CDataQueue{
private:
static CDataQueue* m_cQueue;
// deque <ST_MONITORING_RESULT> m_deQueue;
queue <ST_MONITORING_RESULT> m_deQueue;
CRITICAL_SECTION m_stCriticalSection;
CDataQueue();
~CDataQueue();
public:
static CDataQueue* getDataQueue(){
if (m_cQueue == NULL){
m_cQueue = new CDataQueue();
}
return m_cQueue;
}
deque <ST_MONITORING_RESULT> getQueue();
void pushDataToQueue(ST_MONITORING_RESULT data);
ST_MONITORING_RESULT popDataFromQueue();
};
#endif
//[DataQueue.cpp]
#include "DataQueue.h"
CDataQueue* CDataQueue::m_cQueue = NULL;
CDataQueue::CDataQueue(){
::InitializeCriticalSection(&m_stCriticalSection);
// m_mutex = PTHREAD_MUTEX_INITIALIZER;
}
CDataQueue::~CDataQueue(){
::DeleteCriticalSection(&m_stCriticalSection);
}
::deque <ST_MONITORING_RESULT> CDataQueue::getQueue(){
return m_deQueue;
}
void CDataQueue::pushDataToQueue(ST_MONITORING_RESULT data){
::EnterCriticalSection(&m_stCriticalSection);
m_deQueue.push_back(data);
::LeaveCriticalSection(&m_stCriticalSection);
}
ST_MONITORING_RESULT CDataQueue::popDataFromQueue(){
::EnterCriticalSection(&m_stCriticalSection);
ST_MONITORING_RESULT data = m_deQueue.front();
m_deQueue.pop_front();
::LeaveCriticalSection(&m_stCriticalSection);
return data;
}
Sitting at the top of the <queue> header from the MS implementaiton of the standard library, we find...
// queue standard header
#pragma once
#ifndef _QUEUE_
#define _QUEUE_
Which means your usage of that identifier for your own header fencepost is precluding the MS header body from being pulled in. Thus, no std::queue for you. Use a different id, preferably something that doesn't violate usage rules for macro constants reserved for the implementation (like this one).
And that, kids, is why we don't use identifiers reserved for implementation usage. For more information, read this question: "What are the rules about using an underscore in a C++ identifier?"
When I include this header File "pathfinding.h":
#pragma once
#include <BWAPI.h>
#include "BWAPI/TilePosition.h"
#include <vector>
#include "PathNode.h"
#include "Logger.h"
#include "ArgosMap.h"
#include "MapField.h"
#include "Utils.h"
#include "ComparePathNodePointer.h"
using namespace BWAPI;
class Pathfinding {
private:
std::vector<PathNode*> openList;
std::vector<PathNode*> closedList;
std::vector<Position*> buildpath(PathNode* targetNode);
void expandNode(PathNode* currentNode, MapField* targetField);
ArgosMap* argosMap;
public:
Pathfinding();
~Pathfinding();
std::vector<Position*> getShortestPath(MapField* startField, MapField* targetField);
};
In this header File "UnitAgent.h":
#pragma once
#include <BWAPI.h>
#include <vector>
#include "ArgosMap.h"
#include "Pathfinding.h"
using namespace BWAPI;
class UnitAgent {
protected:
Unit* unit;
UnitType unitType;
int unitID;
std::vector<Position*> trail;
Position target;
public:
UnitAgent(Unit* unit);
std::vector<Position*> getTrail();
Position getTarget();
Position* getPosition();
int getUnitID();
void setTarget(Position target);
void addPositionToTrail(Position* targetLocation);
void moveTo(TilePosition* targetPosition);
};
I get like a million errors mostly error C2143, C2065. But thats not true, the errors do not exist. When I include the header file in another file its all totally fine (except naturally for the stuff that needs the specific header file).
Any Ideas what I should check. Anyone an Idea how i can check my C++ Code, in a way Eclipse checks my java code. I mean why doesnt Visual Studio do that?
This kind of directive should not be in a header file
using namespace BWAPI;
To start with, why do you need all this
#include <BWAPI.h>
#include "BWAPI/TilePosition.h"
#include <vector>
#include "PathNode.h"
#include "Logger.h"
#include "ArgosMap.h"
#include "MapField.h"
#include "Utils.h"
#include "ComparePathNodePointer.h"
using namespace BWAPI;
in pathfinding.h? Just forward declaring ArgosMap, MapField, PathNode, and Position like
class ArgosMap;
class MapField;
class PathNode;
class Position;
is sufficient for pathfinding.h looking at the declaration of Pathfinding class, the stuff above should go to pathfinding.cpp if it is necessary for implementation of Pathfinding methods. The less stuff and dependencies you have in your headers, the easier it will be to debug.
Declarations in pathfinding.h look fine, problem is that some of the methods are not implemented/are not implemented properly. To find out what this methods are, you would need to narrow the scope of the problem - by removing unnecessary dependencies to start with.
Including pathfinding.h in files that do not use it's methods/methods from other headers included would always work fine...
#ifndef _MY_OPENCLPLATFORM_
#define _MY_OPENCLPLATFORM_
#include "OpenCL.h"
namespace my
{
class OpenCLPlatform
{
cl_platform_id mplatformID;
cl_uint mnumDevices;
std::vector<OpenCLDevice> mdevices; // OpenCLDevice was not declared in this scope
public:
OpenCLPlatform(cl_platform_id platformID);
void getDevices();
void printInfo();
cl_platform_id& getPlatformID();
};
}
#endif
#ifndef _MY_OPENCLDEVICE_
#define _MY_OPENCLDEVICE_
#include "OpenCL.h"
namespace my
{
class OpenCLDevice
{
cl_device_id mdeviceID;
public:
OpenCLDevice(cl_device_id device);
void printInfo();
void printDeviceType(cl_device_type deviceType);
};
}
#endif
#ifndef _MY_OPENCL_
#define _MY_OPENCL_
#if defined(__APPLE__) || defined(MACOSX)
#include <OpenCL/opencl.h> // This works only for XCODE compiler
#else
#include <CL/cl.h>
#endif
#include <cassert>
#include <iostream>
#include <vector>
#include "Exception.h"
#include "OpenCLDevice.h"
#include "OpenCLPlatform.h"
namespace my {
class OpenCLDevice;
class OpenCLPlatform;
class OpenCL;
class OpenCL
{
cl_uint mnumPlatforms;
std::vector<OpenCLPlatform> mplatforms;
void getPlatforms();
public:
OpenCL();
~OpenCL();
void quickSetup();
void printPlatformVersions();
};
}
#endif
Does the the ordering "class OpenCLDevice; class OpenCLPlatform; class OpenCL;" matter? Sometimes, header files depend on each other which can lead to "hard to follow" or convoluted inclusions...Do you have a "one way" technique to deal with convoluted inclusions that you use all the time?
Edit:
I changed the code to match my real problem. If you look at the code above, the compiler is saying that 'OpenCLDevice was not declared in this scope'.
Edit:
I finally got the code to work, and this is what I did:
1. add #include "OpenCLDevice.h"in OpenCLPlatform.h
2. compile
3. remove #include "OpenCLDevice.h"in OpenCLPlatform.h
4. compile
It works now!
Edit:
I cleaned the project and removed all dependencies, and I'm getting the same errors again.
Edit:
I think compiler did something to the code. It may have chose to not include libraries that aren't used in the header and source file, but are used in other headers and source codes
Since you are including classa.h and classb.h where both classes are (presumably) defined, you shouldn't even need the forward declaration.
However, if you did not include them, then no, order of the declarations wouldn't matter. As long as as a class is forward declared before it is used you should be OK.
I see two potential issues:
Your #include "OpenCL.h" may not include the file you expect (yours), but instead some system file.
Forward declarations can't be used in your case. It works only when you have pointers or references to class instances. Your vector<OpenCLPlatform> requires the class declaration (i.e. inclusion of the corresponding header).
After fixing the previous problem (see my one other question that I have asked). I had declared more classes.
One of these is called CombatAdmin which does various things: (Header file)
#ifndef COMBATADMIN_H
#define COMBATADMIN_H
#include <string> // Need this line or it complains
#include <Player.h>
#include <Sound.h>
#include <Enemy.h>
#include <Narrator.h>
using namespace std;
class Enemy;
class Player;
class CombatAdmin // Code yet to be commented here, will come soon.
{
public:
CombatAdmin();
void healthSet(double newHealth, string playerName);
void comAdSay(string sayWhat);
void playerFindsChest(Player *player,Weapon *weapon,Armour *armour);
void youStoleOurStuffEncounter(Player *player);
void comAdWarning(string enemyName);
void comAdAtkNote(string attack, double damage,string target,string aggresor);
void entDefeated(string entName);
void comAdStateEntHp(string ent, double hp);
void comAdStateScanResults(string enemyName, double enemyHealth);
string doubleToString(double number);
string intToString(int number);
bool isRandEncounter();
void randomEncounter(Player *player,Sound *sound,Narrator *narrator);
bool combatRound(Player *player, Enemy *enemy, Sound *sound, bool ran);
void playerFindsItem(string playerName,string itemName,double itemWeight,double playerWeight);
void playerFindsGold(string playerName,double coinCnt,double playerCoinCnt);
};
#endif // COMBATADMIN_H
It is then instanced in the main.cpp file like this: (Snippet of the main.cpp file)
#include <iostream> // Required for input and output
#include <Item.h> // Item header file.
#include <Weapon.h> // Header files that I have made for my classes are needed for this program
#include <sstream> // Needed for proper type conversion functions
#include <windows.h> // for PlaySound() and other functions like sleep.
#include <time.h> // Needed to seed the rand() function.
#include <mmsystem.h> // Not sure about this one, possibly defunct in this program.
#include <stdio.h> // Needed for a similar kind of output as iostream for various functions error msgs.
#include <irrKlang.h> // The header file of the sound lib I am using in this program.
#include <Narrator.h> // The narrators's header file.
#include <Pibot.h> // Other header files of classes.
#include <Armour.h>
#include <Player.h>
#include <Weapon.h>
#include <CombatAdmin.h>
using namespace irrklang;
using namespace std;
// Forward referenced functions
void seedRandom(); // Seeds the random number so it will be random as apposed to pseudo random.
string getPlayerName(string temp); // Gets the player's new name.
int main(int argc, char* argv[])
{
// Variables and object pointers declared here.
CombatAdmin *comAd = new CombatAdmin(); // Handles combat.
Narrator *narrator = new Narrator(); // The Narrator that says stuff
Pibot *piebot = new Pibot(); // PIbot, the player's trusty companion
string temp; // Temp string for input and output
However, when I try to compile the project, I get the following error:
C:\Documents and Settings\James Moran.HOME-B288D626D8\My Documents\C++ projects\Test Project\main.cpp|59|undefined reference to `CombatAdmin::CombatAdmin()'|
I am using the Code::Blocks IDE (ver 10.05), with the GNU GCC compiler. The project is of type "Console application". I am using windows XP 32 bit SP3.
I have tried changing to search directories to include where the object files are, but no success there.
As can be seen from the code, the narrator and PIbot are instanced just fine. (then used, not shown)
My question is, therefore, what do I need to do to stop these errors occurring? As when I encountered similar "Undefined reference to x" errors before using libraries. I had just forgotten to link to them in Code::Blocks and as soon as I did, they would work.
As this class is of my own making I am not quite sure about this.
Do say if you need more information regarding the code etc.
You have declared the default constructor (CombatAdmin()) and thus prevented the compiler from automatically generating it. Thus, you either need to 1) remove declaration of the default constructor from the class, or 2) provide an implementation.
I had this kind of error and the cause was that the CombatAdmin.cpp file wasn't selected as a Build target file: Prject->Properties->Build targets
Are you sure you've to include your header as:
#include <CombatAdmin.h>
?
I think you need to include your header file as:
#include "CombatAdmin.h"
And same for other headers written by you, like these:
#include "Armour.h"
#include "Player.h"
#include "Weapon.h"
//and similarly other header files written by you!
See this topic:
What is the difference between #include <filename> and #include "filename"?
My solution was just to add a line in the header before the class defenition:
class CombatAdmin;