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.
Related
I am new to C++ programming and have a compiler error that I can't figure out. Any help would be appreciated.
Here is the build log:
C:\Dev\MemberTest\Entity.cpp|6|error: redefinition of 'class Entity::Entity'|
C:\Dev\MemberTest\Entity.h|6|error: previous definition of 'class Entity::Entity'|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
The program has Main.cpp, Entity.h and Entity.cpp (I was just tinkering with how to implement headers and source files).
#include <iostream>
#include "Entity.h"
int main()
{
Entity::Entity Person("Grant", true); //Create person and set membership
std::cout << Person.getName() << " is a member: " << Person.getMembership() << std::endl;
return 0;
}
#ifndef ENTITY_H_INCLUDED
#define ENTITY_H_INCLUDED
namespace Entity
{
class Entity
{
private:
std::string name;
bool member;
public: //Get, set, constructor calls for a bool and string.
Entity(std::string y, bool x);
bool getMembership();
std::string getName();
void setMembership(bool x);
};
}
#endif // ENTITY_H_INCLUDED
#include <string>
#include "Entity.h"
namespace Entity
{
class Entity
{
private:
std::string name;
bool membership;
public:
Entity(std::string y, bool x):name(y),membership(x){}
bool getMembership(){return this->membership;};
std::string getName(){return this->name;};
void setMembership(bool x){this->membership=x;};
};
}
I've looked around for a solution and found questions like this: error: redefinition of class but the solutions I'm seeing aren't relevant to my program because I'm already using #ifndef.
Since I'm not sure what other info might be needed here goes: All three files are in the same folder and there aren't other source or header files in that folder. Oddly enough if I comment out the #include "Entity.h" in the Entity.cpp file and reference the source in Main.cpp instead of Entity.h it compiles and runs fine. I'm coding on Code::Blocks and with the GCC Compiler. Thanks again for any help.
The implementation file (Entity.cpp) should not contain the class definition again. Instead, you write non-inline definitions ("out of class"):
#include <string>
#include "Entity.h"
namespace Entity
{
Entity::Entity(std::string y, bool x) : name(y), membership(x) {}
bool Entity::getMembership() { return membership; }
std::string Entity::getName() { return name; }
void Entity::setMembership(bool x) { membership = x; }
}
Also note that your Entity.h header depends on std::string which requires the #include <string> header there, not just in the implementation file (Entity.cpp). There is no need to use this-> here nor some of the semicolons (;).
Oddly enough if I comment out the #include "Entity.h" in the Entity.cpp file and reference the source in Main.cpp instead of Entity.h it compiles and runs fine
That is because you can define functions inline in the class (instead of putting them in the implementation file). What you did is implement all of them in the class definition, and therefore you don't need an implementation file anymore.
In other words, your Entity.cpp looked like a header file with a full implementation of the class, although you called it .cpp rather than .h. Thus if you include that file, it would work.
Ok, so before you all go pointing me to the different posts where this question has already been addressed, I wish to disclaim that I have indeed solved my issue following this post here.
This post is more about digging beneath the surface of how the compiler works.
Here we go...
Menu.h includes MenuEntry.h and MenuEntryKey.h, like so:
#ifndef MENU_H
#define MENU_H
#include <cstdlib>
#include <map>
#include <string>
#include "MenuEntry.h"
#include "MenuEntryKey.h"
class Menu
{
public:
// ctor, dtor, copy control
Menu(const std::map<MenuEntryKey, MenuEntry> &opts = std::map<MenuEntryKey, MenuEntry>(),
const unsigned numF = 0, const unsigned numD = 0) : options_(opts),
numFoodOptions_(numF),
numDrinkOptions_(numD) {}
~Menu() {}
Menu(const Menu &);
Menu &operator=(const Menu &);
// entry select funcs: both simply return a random menu selection's name, based on the provided entry type.
inline const std::string selectOption(const char);
private:
const std::map<MenuEntryKey, MenuEntry> options_;
const unsigned numFoodOptions_;
const unsigned numDrinkOptions_;
// private accessors; Guests must only be able to select a valid option. This can be changed later, if need be.
inline const std::map<MenuEntryKey, MenuEntry> &getOptions() const { return options_; }
inline const std::map<MenuEntryKey, MenuEntry> &getOptions()
{
return (static_cast<const Menu &>(*this)).getOptions();
}
inline const unsigned getNumFoodOptions() const { return numFoodOptions_; }
inline const unsigned getNumDrinkOptions() const { return numDrinkOptions_; }
};
#endif // MENU_H
Showing you MenuEntry.h and MenuEntryKey.h is really not relevant to this question; they are both just standalone components used to build the Menu.
Next, I have a class called DataLoader, which creates a Menu based on plaintext metadata. Here is DataLoader.h:
#ifndef DATALOADER_H
#define DATALOADER_H
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <ctype.h>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include "Menu.h"
#include "MenuEntryKey.h"
#include "MenuEntry.h"
class Menu;
namespace DataLoader
{
const Menu &createMenu();
} // namespace DataLoader
#endif // DATALOADER_H
As it stands, there are no errors in DataLoader.cpp; however, as soon as I remove the MenuEntry.h and MenuEntryKey.h includes from DataLoader.h, like so:
#ifndef DATALOADER_H
#define DATALOADER_H
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <ctype.h>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include "Menu.h"
// Note the missing includes that used to be here.
// "" ""
class Menu;
namespace DataLoader
{
const Menu &createMenu();
} // namespace DataLoader
#endif // DATALOADER_H
I get incomplete type is not allowed (DataLoader.cpp):
#include "DataLoader.h"
const Menu &DataLoader::createMenu()
{
std::ifstream in;
in.open("../../../../meta/menu.md");
if (!in)
{
std::cout << "Unable to open file.\n";
exit(-1);
}
std::map<MenuEntryKey, MenuEntry> options;
std::string line;
while (std::getline(in, line))
{
if (line.size() == 0)
continue;
if (line[0] == '-')
{
char entryType = toupper(line[1]);
unsigned num = 0;
std::vector<std::string> tokens;
std::getline(in, line);
while (line[0] != '^')
{
boost::algorithm::split(tokens, line, boost::algorithm::is_any_of(" "));
MenuEntryKey key; //INCOMPLETE TYPE ERROR HERE
}
}
} // end while
}
The reason this is so baffling to me is Menu.h includes MenuEntry.h and MenuEntryKey.h! Would that not imply that including Menu.h would also include the latter two? Please enlighten me on this strange occurrence.
The reason I DON'T want to include MenuEntry.h and MenuEntryKey.h in DataLoader.h is because I have learned it is generally a good practice to avoid including things that have already been included, which is something I am currently trying to get a better grip on.
Note that if you look at my headers closely, you'll see that I double include some STL headers, which was no accident; I just have yet to find and integrate a clean method of taking care of it.
Let me know if you need more information. Hopefully, this question is appropriate for SO and I have provided enough detail.
Cheers
EDIT:
I am seeing a little bit of confusion in the comments, so I am going to try to clarify my question as best as I can.
• Menu.h includes BOTH MenuEntry.h and MenuEntryKey.h.
• MenuEntry.h only includes and MenuEntryKey.h includes literally nothing. AFAIK, There are no circular dependencies between Menu.h, MenuEntry.h, and MenuEntryKey.h.
• When DataLoader.cpp includes ONLY Menu.h, the preprocessor cannot find a complete definition for MenuEntryKey.h OR MenuEntry.h, even though both of these files are included by Menu.h.
If including works similarly to copying and pasting code, then why can't the preprocessor find complete definitions for MenuEntry and MenuEntryKey in DataLoader.cpp? Shouldn't including Menu.h copy and paste the code from that header, which in turn, copies and pastes the headers MenuEntry.h and MenuEntryKey.h???
Hope this helps.
As requested, I will provide a basic working example of what I am talking about. Please give me 5 minutes.
EDIT #2:
Here is your minimal reproducible example.
MenuEntryKey.h:
#ifndef MENUENTRYKEY_H
#define MENUENTRYKEY_H
class MenuEntryKey
{
public:
MenuEntryKey(char type = '!', unsigned num = 0) : type_(type), num_(num) {}
private:
const char type_;
const unsigned num_;
};
#endif // MENUENTRYKEY_H
MenuEntry.h:
#ifndef MENUENTRY_H
#define MENUENTRY_H
#include <string>
class MenuEntry
{
const std::string name_;
};
#endif // MENUENTRY_H
Menu.h:
#ifndef MENU_H
#define MENU_H
#include "MenuEntry.h"
#include "MenuEntryKey.h"
class Menu
{
public:
private:
const unsigned numFoodOptions_;
const unsigned numDrinkOptions_;
};
#endif // MENU_H
DataLoader.h:
#ifndef DATALOADER_H
#define DATALOADER_H
class Menu;
namespace DataLoader
{
const Menu &createMenu();
} // namespace DataLoader
#endif // DATALOADER_H
DataLoader.cpp:
#include "DataLoader.h"
#include "Menu.h"
// #include "MenuEntry.h"
// #include "MenuEntryKey.h"
const Menu &DataLoader::createMenu()
{
MenuEntryKey key;
}
Amazingly enough, this skeleton example produces no incomplete type error. Note the two include statements that are commented out.
Why would this work now, when before it didn't? It must have something to do with included headers; could STL header includes cause this, or only includes of user-defined headers? Would include guards stop this from happening?
Thanks for all your help, I really appreciate it.
I've got two files, list.cpp and Header.h. Segments of the files are below. I know that if the header file is for a class, it is setup different. E.g.
class MyClass
{
public:
void foo();
int bar;
};
However, since I'm not really working with a class here (correct me if I'm wrong), am I not able to declare things under public: and private like below?
Also, if I were to place the global variable rescan in the header file as a member variable, below the function definitions, only the main function can see the variable. Why is it not within the scope of the other functions?
list.cpp:
#include <boost/algorithm/string.hpp>
#include <vector>
using namespace std;
vector<int> results;
bool rescan;
int main()
{
vector<vector<string>> list;
int success = readFile(list);
vector<vector<string>> bad = findMe(list);
system("pause");
return 0;
}
vector<vector<string>> findMe(vector<vector<string>> find)
{
rescan = true;
}
Header.h:
#pragma once
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#include <string>
#include <vector>
std::vector<std::vector<std::string>> findMe(std::vector<std::vector<std::string>>);
#endif
EDIT: I tried this in my header file:
public:
bool rescan;
But I got "syntax error: 'public'
If you want your global to be visible in other translation units (TU) (other files), you have to declare them extern in those other TUs:
Header.h:
// Include guard omitted
extern bool rescan; // Declaration
file.cpp
#include "Header.h"
bool rescan = false; // Definition
// ...
file2.cpp
#include "Header.h" // To see extern bool rescan;
void foo()
{
rescan = true;
}
// ...
I am a total noob.
I have created functions for int to string and string to int conversion.
I want to save them so I can use them in any program, so I can call them like #include <iostream>
Do I do this by creating a class ( which then has no private member variables?)
and if I do it as a class how do I use functions without creating objects?
Basically I want to create my own cmath or string sort of thing but I don't even know what to call it to find out how to make it.
If you have just simple functions you can put them in a namespace, which also acts like a container, then put them in a seperate cpp file together and create a .h file which contains the prototypes.
i.E for mymath.h:
#ifndef MYMATH_H
#define MYMATH_H
namespace mymath
{
int dosomething(int y);
}
#endif
and in the mymath.cpp:
#include "mymath.h"
int mymath::dosomething(int y)
{
}
Then, when you want to use it, you include your #include "mymath.h" file and link the cpp to your project.
mystring.hpp
#ifndef MYSTRING_HPP
#define MYSTRING_HPP
#include <string>
namespace n_mystring
{
std::string & IntToString( int Int );
int StringToInt( std::string & String );
}
#endif
mystring.cpp
#include "mystring.hpp"
std::string & n_mystring::IntToString( int Int ) {
//.... implementation
};
int n_mystring::StringToInt( std::string & String ) {
//.... implementation
};
#include <iostream>
class Tools {
public :
void static sneeze ();
};
void Tools::sneeze ()
{
std::cout << "atchoum";
}
int main () {
Tools::sneeze(); // atchoum
}
I am trying to move from using structs to using classes, and I have a few questions with my - not fully complete, but enough to illustrate my queries - code (thank you in advance for clarifying these):
I am having problems with creating a constructor that takes in arguments, specifically the line in the header file that I have currently left as neighborAtt(int neighbor_id, int att_1, int att_2);.
When using neighborAtt as a struct, I could do it easily as neighborAttributes currentNode(neighborID, att1, att2);. What is the class-equivalent?
In the .cpp file, I know that I need to define the constructor as neighborAtt::neighborAtt().
Do I need to this with the functions (i.e. include neighborAtt::) or is what I've done accurate?
This is my header file:
#if !def connectivity_H
#define connectivity_H
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <sstream>
#include <fstream>
class listAtt;
class vecListAtt;
class neighborAtt //contains the neighbour and associated attributes of a node
{
public:
neighborAtt();
neighborAtt(int neighbor_id, int att_1, int att_2);
vecListAtt connFrFile(int file_ext);
vecListAtt makeList(std::vector<std::list<neighborAtt>> nodeAndInfo, int nodeID, neighborAtt neighAndAtt);
neighborAtt getAtt(std::string currentLine);
private:
int neighborID;
int attribute1;
int attribute2;
};
typedef std::list<neighborAtt> listAtt;
typedef std::vector<listAtt> vecListAtt;
#endif
and the .cpp file:
#include "stdafx.h"
#include "connectivity.h"
neighborAtt::neighborAtt(): neighborID(0), attribute1(0), attribute2(0) {}
//neighborAtt::neighborAtt constructor with arguments
vecListAtt connFrFile(int file_ext)
{
//code
}
neighborAtt getAtt(std::string line)
{
//code
}
For the second constructor (one with the arguments) you do just the same as for one without them. Or did I get the question wrong? It'd be like:
neighborAtt::neighborAtt(int neighbor_id, int att_1, int att_2)
: neighborID(neighbor_id),
attribute1(att_1),
attribute2(att_2)
{
}
And for the methods you must go the same way:
vecListAtt neighborAtt::connFrFile(int file_ext)
{
//code
}