I'm new to C++ and need some help with namespaces.
Following are my 4 files:
node.h <--class interface
node.cpp <--implementation
testNodeFunctions.cpp
testNodeMain.cpp
//node.h
---------------------------------
#include <iostream>
using namespace std;
namespace namespaceName{
class Node {
private:
int data;
public:
void setData( int x);
int getData();
};
//and some more functions
}
//node.cpp
-------------------------------------
#include <iostream>
#include "node.h"
using namespace std;
namespace namespaceName {
//provides implementation of the memeber functions
int Node::getData() const{
return data;
}
void Node::setData(int x){
data=x;
}
}//namespace
//testNodeFunctions.cpp
-------------------------------------
#include <iostream>
#include "Node.h"
using namespace std;
using namespace namespaceName;
void showData(){
//creates a Node object and prints some stuff
Node a=37;
cout<<a.getValue()<<endl;
}
//testNodeMain.cpp
----------------------------------------------
#include <iostream>
#include "Node.h"
void showData();
int main(){
//calls methods from testNodeFunctions
showData();
}
I'm not sure if I'm defining the namespace currently.
How Do I call the showData() function from the testNodeMain.cpp file. Currently I'm getting linker error stating that "undefined reference to namespaceName::Node::methodname"
Thanks so much in advance
Okay. That make sense. I removed , using namespace std from header. I'm compiling the testNodeMain.cpp which has the main(). the TestNodeMain.cpp calls functions from testNodeFunctions.cpp. testNodeFunctions.cpp creates Node object.
In your header file node.h, you have
void setData( int x);
int getData();
where as in your node.cpp file, you have:
int Node::getValue() const{
return data;
}
void Node::setValue(int x){
data=x;
}
You need to change your Node::getValue() const {} to Node::getData() const {}, or change the names of the functions in your header files to int getValue() and void setValue (int x)
The function names in the header files for the class and the actual .cpp file should be the same.
It's really hard to tell without a complete compiling example that induces your problem, but it looks like you forgot to include node.cpp on your link line.
I'm not sure if I'm defining the namespace currently.
That looks fine, although without seeing what you've put inside it I can't say for sure.
How Do I call the showData() function from the testNodeMain.cpp file?
The function needs to be declared before you can call it. Add the following declaration, either after the #include lines in testNodeMain.cpp, or in another header file which must then be included from testNodeMain.cpp:
void showData();
Then you can call the function from main:
int main() {
showData();
}
Currently I'm getting linker error stating that "undefined reference to namespaceName::Node::methodname"
You need to make sure you're compiling and linking all the source files, not just the main one. If you're using GCC, the build command should look something like:
gcc -o testNode testNodeMain.cpp testNodeFunctions.cpp node.cpp
If you're still getting the error in that case, then check that you have actually implemented the methods. If you think you have, then please update the code in your question to include the implementation of one of the missing methods so we can check that for you.
Related
So I have two classes - Dvd and DvdGroup. DvdGroup basically manages an array of dvds and provide manipulative member functions for that class. The problem is whenever I try to compile DvdGroup.cc using the command 'g++ -c Dvd.Group.cc', I get a bunch of errors all related to not having 'Dvd' declared and I'm not sure why.
Here are some errors below:
DvdGroup.h:14:12: error: ‘Dvd’ has not been declared void add(Dvd*);
DvdGroup.h:18:3: error: ‘Dvd’ does not name a type Dvd* dvdCollection[MAX_DVDS];
DvdGroup.cc: In copy constructor ‘DvdGroup::DvdGroup(DvdGroup&)’:
DvdGroup.cc:15:6: error: ‘Dvd’ was not declared in this scope for(Dvd d: dvds){
I feel like I'm missing something and they could all be fixed by one solution because they all involve having the Dvd class undeclared but I can't seem to figure out what. I was wondering if anyone could tell me what I'm doing wrong? I would really appreciate any help with fixing this.
DvdGroup.cc:
#include <iostream>
using namespace std;
#include "DvdGroup.h"
DvdGroup::DvdGroup(int n){
numDvds = n;
}
DvdGroup::DvdGroup(DvdGroup& dvds){
numDvds = dvds.numDvds;
for(Dvd d: dvds){
Dvd newDvd = Dvd;
}
}
DvdGroup::~DvdGroup(){
//code
}
void DvdGroup::add(Dvd* d){
//code
}
DvdGroup.h:
#ifndef DVDGROUP_H
#define DVDGROUP_H
#define MAX_DVDS 15
#include <string>
using namespace std;
class DvdGroup
{
public:
DvdGroup(int);
DvdGroup(DvdGroup&);
~DvdGroup();
void add(Dvd*);
private:
Dvd* dvdCollection[MAX_DVDS];
int numDvds;
};
#endif
Don't know if the Dvd header file is needed, but here:
Dvd.h:
#ifndef DVD_H
#define DVD_H
#define MAX_DVDS 15
#include <string>
class Dvd{
public:
Dvd(string, int);
void set(string, int);
Dvd(Dvd&);
int getYear();
~Dvd();
void print();
private:
string title;
int year;
};
#endif
What you need to do is to provide Dvd class definition for DvdGroup class. It is needed to know what type of symbol is this. Solution for your problem should be addition of:
#include "Dvd.h"
line to DvdGroup.h file.
I am farily new to C++ and I have been stuck with this problem for a few hours now. I am trying to setup the foundations for a video game related experience calculator, but I can't get past this problem.
main.cpp
#include <iostream>
#include "Log.h"
using namespace std;
int main()
{
Log Logs;
enter code here
struct ChoppableLog Yew;
Logs.initialiseLog(Yew, 60, 175);
return 0;
}
Log.h
#ifndef LOG_H
#define LOG_H
struct ChoppableLog
{
int level;
int xp;
};
class Log
{
public:
void initialiseLog(struct ChoppableLog &par1_log, int par2_int, int par3_int);
Log();
};
#endif // LOG_H
Log.cpp
#include "Log.h"
#include <iostream>
using namespace std;
Log::Log()
{
}
void initialiseLog(struct ChoppableLog &par1_log, int par2_int, int par3_int)
{
}
The error I get is
C:\Users\Murmanox\Documents\C++\C++ Projects\CodeBlocks\Class Files Test\main.cpp|11|undefined reference to `Log::initialiseLog(ChoppableLog&, int, int)'|
I can post more details if necessary.
You have to define Log::initialiseLog with its full name, like so:
void Log::initialiseLog(struct ChoppableLog &par1_log, int par2_int, int par3_int)
{ }
What you are doing is defining a new, free function of the name initialiseLog instead of defining the member function of Log.
This leaves the member function undefined, and, when calling it, your compiler (well, technically linker) will be unable to find it.
The definitions of functions in a header file should specify the scope. In your case, you should define initialiseLog() function in your cpp file as follows:
void Log::initialiseLog(struct ChoppableLog &par1_log, int par2_int, int par3_int)
{
}
I got three .cpp files and two header files.
But when i compile them, meaning the Point.cpp, Data.cpp and main.cpp, it will say
Data.h:6:7 redefinition of Data at 'Data.h'
Data.h:6:7 previously definition of 'class Data'
Below is my Data.h(previously known as 2.h at above)
#include <iostream>
#include <string>
using namespace std;
class Data
{
private:
string sType;
public:
Data();
Data(string);
void setSType(string);
string getSType();
};
Below is my data.cpp
#include "Data.h"
Data::Data()
{
sType = "";
}
Data::Data(string s)
{
sType = s;
}
void Data::setSType(string ss)
{
sType = ss;
}
string Data::getSType()
{
return sType;
}
Below is my PointD.h (previously known as 3.h)
#include <iostream>
#include <string>
#include "Data.h"
using namespace std;
class PointD
{
private:
int x
Data data1;
public:
PointD();
PointD(int,Data);
void setX(int);
void setData(Data);
int getX();
Data getData();
};
Below is my PointD.cpp
#include "PointD.h"
PointD::PointD()
{
x = 0;
}
PointD::PointD(int xOrdinate,Data dd)
{
x = xOrdinate;
data1 = dd;
}
void PointD::setXordinate(int Xordinate)
{
x = Xordinate;
}
void PointD::setData(Data dd)
{
data1 = dd;
};
int PointD::getXordinate()
{
return x;
}
Data PointD::getData()
{
return data1;
}
This is my main.cpp
#include <iostream>
#include <string>
#include "Data.h"
#include "PointD.h"
using namespace std;
int main()
{
const int MAX_NUM = 20;
Data ldata[MAX_NUM];
PointD pointd[MAX_NUM];
//more codes..
}
But when i compile them, meaning the Point.cpp, Data.cpp and main.cpp, it will say
Data.h:6:7 redefinition of Data at 'Data.h'
Data.h:6:7 previously definition of 'class Data'
Can anybody let me know whats actually went wrong here..
You need to use include guards, or the easiest:
#pragma once
in your header files
See Purpose of Header guards for more background
Idea: 1.hpp
#ifndef HEADER_GUARD_H1_HPP__
#define HEADER_GUARD_H1_HPP__
// proceed to declare ClassOne
#endif // HEADER_GUARD_H1_HPP__
In each of your header files write:
#ifndef MYHEADERNAME_H
#define MYHEADERNAME_H
code goes here....
#endif
Its better like this:
#ifndef DATA_H /* Added */
#define DATA_H /* Added */
#include <iostream>
#include <string>
// using namespace std; /* Removed */
class Data
{
private:
std::string sType;
public:
Data();
Data( std::string const& ); // Prevent copy of string object.
void setSType( std::string& ); // Prevent copy of string object.
std::string const& getSType() const; // prevent copy on return
std::string& getSType(); // prevent copy on return
};
#endif /* DATA_H */
The big fix is adding ifndef,define,endif. The #include directive works as if copying and pasting the .h to that line. In your case the include from main.cpp are:
main.cpp
-> Data.h (1)
-> Point.h
-> Data.h (2)
At (2), Data.h has already been `pasted' into main.cpp at (1). The class declaration of Data, i.e. "class Data{ .... };" , appears twice. This is an error.
Adding include guards to the top and bottom of every .h are standard practice to avoid this problem. Don't think about it. Just do it.
Another change I'd suggest is to remove any "using namespace ..." lines from any .h . This breaks the purpose of namespaces, which is to place names into separate groups so that they are not ambiguous in cases where someone else wants an object or function with the same name. This is not an error in your program, but is an error waiting to happen.
For example, if we have:
xstring.h:
namespace xnames
{
class string
{
...
};
}
Foo.h
#include <xstring>
using namespace xnames;
...
test.cxx:
#include "Foo.h"
#include "Data.h" // Breaks at: Data( string ); -- std::string or xnames::string?
...
void test()
{
string x; // Breaks. // std::string or xnames::string?
}
Here the compiler no longer knows whether you mean xnames::string or std::string. This fails in test.cxx, which is fixable by being more specific:
void test()
{
std::string x;
}
However, this compilation still now breaks in Data.h. Therefore, if you provide that header file to someone, there will be cases when it is incompatible with their code and only fixable by changing your header files and removing the "using namespace ...;" lines.
Again, this is just good coding style. Don't think about it. Just do it.
Also, in my version of Data.h, I've changed the method parameters and return types to be references (with the &). This prevents the object and all of its state from being copied. Some clever-clogs will point our that the string class's is implementation prevents this by being copy-on-write. Maybe so, but in general, use references when passing or returning objects. It just better coding style. Get in the habit of doing it.
In my Function.h file:
class Function{
public:
Function();
int help();
};
In my Function.cpp file:
#include "Function.h"
int Function::help() //Error here
{
using namespace std;
cout << "Help";
return 1;
}
In my Main.cpp
#include <iostream>
#include "Function.h"
using namespace std;
int menu(){
Function fc;
fc.help();
return 1;
}
int main(int args, char**argv){
return menu();
}
Error is : ‘Function’ has not been declared
Can anybody tell me why? Thank you.
I tried like this and the problem is solved, but I dont really understand why:
In Function.h file:
I use
class Function{
public:
int status;
Function():status(1){}
int help();
};
instead of the old one
class Function{
public:
Function();
int help();
};
All your include statements are missing the #:
#include "Function.h"
^
Everything else looks fine, though you need to also #include <iostream> in Function.cpp since you're using cout.
Here is the Function.cpp that I got to compile and run:
#include "Function.h"
#include <iostream>
int Function::help() // No error here
{
using namespace std;
cout << "Help";
return 1;
}
Function::Function()
{
}
I had a similar problem. Make sure that you only have the required header files. I had two header files both including each other and it spit out this mistake.
You have created a declaration for the constructor of the Function class without including it in your implementation (cpp file).
#include "Function.h"
Function::Function(){
// construction stuff here
}
int Function::help() //Error here
{
using namespace std;
cout << "Help";
return 1;
}
In the first Function.h file you have declared the constructor but not defined it. In the second Function.h file (the one that works) you have defined and declared the Function constructor. You can either define and declare in the header or file, or declare in the header file and define in the Function.cpp file.
For example, declare in the header file "Function.h":
class Function
{
Function();
}
and define here in "Function.cpp":
Function::Function(){}
Or the alternative is to declare and define in the header file "Function.h":
Class Function
{
Function(){}
}
The other thing that you have done in the second version of the header file is to initialise the member variable "status" in the "member initialisation list" which is a good thing to do (See Effective C++ by Scott Meyers, Item 4). Hope this helps :)
I've these 2 files, but the interface (and the compiler) give me this error, can you help me find what is wrong?Is really strange... should I define all body of my methods in the .cpp file?
//GameMatch.h
#pragma once
#include "Player.h"
namespace Core
{
class GameMatch
{
private:
const static unsigned int MAX_PLAYERS=20;
unsigned int m_HumanControlled;
Score* m_LastDeclaredScore;
Score* m_LastScore;
unsigned int m_MaxPlayers;
Player* m_Players[MAX_PLAYERS];
unsigned int m_PlayerTurn;
inline void NextTurn() { m_PlayerTurn=(m_PlayerTurn+1U)%m_MaxPlayers; }
public:
GameMatch(void);
~GameMatch(void);
void RemovePlayer(Player* _player);
inline Player* getPlayingPlayer() { return m_Players[m_PlayerTurn]; }
};
}
and
//Player.h
#pragma once
#include "IController.h"
#include "GameMatch.h"
#include <string>
#include <Windows.h>
using namespace Core::Controller;
using namespace std;
namespace Core
{
class Player
{
private:
IController* m_Controller;
unsigned int m_Lives;
GameMatch* m_GameMatch;
string m_Name;
bool m_TurnDone;
public:
inline void Die()
{
m_Lives-=1U;
if (m_Lives<1) m_GameMatch->RemovePlayer(this);//m_GameMatch is the first error
}
inline const string& getName() { return m_Name; }
inline bool IsPlayerTurn() { return (m_GameMatch->getPlayingPlayer()==this); }//m_GameMatch is the second error
virtual void Play()=0;
inline Player(GameMatch* _gameMatch,const char* name,unsigned int lives=3)
{
m_GameMatch=_gameMatch;
m_Name=name;
m_Lives=lives;
}
inline void WaitTurn() { while(!IsPlayerTurn()) Sleep(1); }
virtual ~Player()
{
delete m_Controller;
}
};
}
But as you can see, m_GameMatch is a pointer, so I don't understand why this error, maybe for "recursive inclusion" of header files...
UPDATE 1:
//GameMatch.h
#pragma once
#include "Score.h"
#include "Player.h"
namespace Core
{
class GameMatch
{
private:
const static unsigned int MAX_PLAYERS=20;
unsigned int m_HumanControlled;
Score* m_LastDeclaredScore;
Score* m_LastScore;
unsigned int m_MaxPlayers;
Player* m_Players[MAX_PLAYERS];
unsigned int m_PlayerTurn;
inline void NextTurn();
public:
GameMatch(void);
~GameMatch(void);
void RemovePlayer(Player* _player);
inline Player* getPlayingPlayer();
};
}
and
//Player.h
#pragma once
#include "IController.h"
#include "GameMatch.h"
#include <string>
#include <Windows.h>
using namespace Core::Controller;
using namespace std;
namespace Core
{
class Player
{
private:
IController* m_Controller;
unsigned int m_Lives;
GameMatch* m_GameMatch;
string m_Name;
bool m_TurnDone;
public:
inline void Die();
inline const string& getName();
inline bool IsPlayerTurn();
virtual void Play()=0;
inline Player(GameMatch* _gameMatch,const char* name,unsigned int lives=3);
inline void WaitTurn();
virtual ~Player();
};
}
These are the 2 headers now, however it's still not working, if I don't include Player.h and forward declare a class in this way inside GameMatch.h:
class Player;
It works, however what if I want use some Player methods?I should re-forward declare everything... isn't this what header files are done for? I can include an header file in a lot of places... why can't I do it in this case?
SOLUTION:
The answer is from Alf P. Steinbach on chat:
yes, and the answer you got seems to be correct. the cyclic header dependency is a problem. there might be other problems also, but the cyclic dependency is a big one.
you don't need a full definition of a class in order to use T*.
so the usual breaking of the cycle is to just forward-declare a class, like
class Player;
that tells the compiler that Player is a class, so you can use Player* and Player&, and even declare member functions that return Player (although you can't define such a function until Player class is fully defined)
well as a concrete example, all that's needed for the Core::GameMatch class definition is a forward declaration of class Player.
then in implementation file you can include "player.h".
if it's needed for GameMatch implementation.
if you draw the files as little boxes and draw arrows to show includes, you'll see that that gets rid of the cyclic dependency
This said, he explain that the answer I got is the correct one so I'll mark OJ's
You should definitely avoid the cyclic header include.
Break the content of your functions out into .cpp files instead of putting everything in header files. Also, rather than #include things every time, just forward declare instead.
If you remove the cyclic include, your code will most likely work.